Cocos2dJS 3.0 RC3中 通过JSB 使用 Sqlite3

How To using sqlite3 in jsb
本教程主要和大家一起熟悉JSB 以及在支持JSB的环境下 使用sqlite3

准备&前戏:
* 本教程是基于MacOS 不过Windows差不多啦
* 本教程有部分软件比如python的扩展功能 mac windows上都有的 本教程使用的是Mac上的安装方式

   1.创建Cocos2dx JS 项目  http://www.cocos2d-x.org/docs/manual/framework/html5/v2/cocos-console/zh 
 cocos new -p com.package.client -l js -d ./ projectName 
 
```
 

 2.以下 项目目录 用${PROJECT} 代替 指的是你创建项目时 指定的路径

 
开始:

 1,首先 你需要在 http://www.sqlite.org/download.html%20 下载 sqlite3.h sqlite3.c这两个基础文件(如果不高兴下载的话 后面我会把教程源码放上来)


2,  包装类选用 我在基于 http://www.adp-gmbh.ch/sqlite/wrapper.html 的基础上修改了包装类 加入平台初始化信息 主要是处理Android目录权限的问题了
 
3,复制以上文件至Classes目录下 在xcode中请加入至开发环境 Classes右键 Add Files To "${PROJECT_NAME}" 
     这个时候 你的目录结构应该是这样的
       


4,测试下是否正常吧
 4.1 请自行编辑一个sqlite.db文件 或者可以把示例下载 获取 project/res/data.db 文件 放入${PROJECT} /res目录下
        4.2 修改AppDelegate.cpp 在applicationDidFinishLaunching()里加入以下代码  需要在AppDelegate.cpp里include SQLiteWrapper.h
 
 auto wrapper = new SQLiteWrapper();
          wrapper->initializing("data.db", "res", "”);
 
```


         4.3 运行项目吧
 日志输出:

 cocos2d: 
数据库打开状态
 1

    恭喜你!! 不过还没完 下面是JSB
        


JSB准备:


 * 参考文章 http://www.cocos2d-x.org/wiki/How_to_bind_C++_to_Javascript?project_id=cocos2d-x
 * 上例部分仅供参考 也就是说有部分已经不对了 详情见下
 1,下载 http://llvm.org/releases/download.html#3.3  解压到 $HOME/bin 目录  没有bin自行创建.
 2,下载安装MacPorts  http://www.macports.org/install.php
 3,python插件支持  如果你已经做了2 请直接在终端执行
 
 sudo port install python27 py27-yaml py27-cheetah
 
```
  4,下载android-ndk-r9b 
 如果以上你执行完成了 并且放置的目录都清楚了 OK 下一步


JSB开始:


 1,进入目录 ${PROJECT}/tools/bindings-generator/test
 2,观察test例子 一起开始AUTO JSB吧
 
 3,首先 建立目录 ${PROJECT}/tools/bindings-generator/test/sqlite_bindings 并复制SQLiteWrapper.h SQLiteWrapper.cpp sqlite3.h 至该目录 就是我们想要进行绑定的类啦 
 4,修改userconf.ini 
 至 ${PROJECT}/tools/bindings-generator/test目录 复制文件 userconf.ini.sample 并重命名为userconf.ini   修改userconf.ini  文件  
 
 
         androidndkdir=/path/to/android-ndk   //你下载的ndk的路径
 clangllvmdir=/path/to/clang+llvm-3.3  //你下载的llvm-3.3路径
 cxxgeneratordir=${PROJECT}/tools/bindings-generator //这个你只需要指向到你的${PROJECT}/tools/bindings-generator目录下
  
```
 
 5,修改user.cfg
  至 ${PROJECT}/tools/bindings-generator/test 目录   复制文件 user.cfg.sample 并重命名为user.cfg   修改user.cfg  文件  
 
PYTHON_BIN=/opt/local/bin/python //这里就是你的python安装目录里的python执行文件 which python目录也可 
```
 


 6,   修改ini文件  复制文件${PROJECT}/tools/bindings-generator/test/test.ini  粘贴并重命名 db.ini


       下面是示例代码 请同仁注意 #后面中文的那些修改 然后改动至自己的db.ini上 偷懒直接用也没问题 本例中 如可 请用下面的
 
name = sqlite_binding #
prefix = autogensqlitebindings#后缀
classes = SQLiteStatement SQLiteWrapper#绑定的类


android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/include
android_flags = -D_SIZE_T_DEFINED_


clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
clang_flags = -nostdinc -x c++ -std=c++11


simple_test_headers = -I%(cxxgeneratordir)s/test/sqlite_binding#头文件


extra_arguments = %(android_headers)s %(clang_headers)s %(android_flags)s %(clang_flags)s %(simple_test_headers)s %(extra_flags)s


headers = %(cxxgeneratordir)s/test/sqlite_binding/SQLiteWrapper.h#头文件


target_namespace = sql#命名空间 指定了在JS端调用需要加入命名空间才能调用
remove_prefix =
skip = 
base_objects =
abstract_classes =
classes_have_type_info = no
rename =
rename_functions =
rename_classes =
# classes for which there will be no "parent" lookup
classes_have_no_parents =


# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip =


# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = yes



 
```


 7,复制 ${PROJECT}/tools/bindings-generator/test/test.sh 并重命名 db.sh 修改最后一行
 LD_LIBRARY_PATH=${CXX_GENERATOR_ROOT}/libclang $PYTHON_BIN ${CXX_GENERATOR_ROOT}/generator.py ${CXX_GENERATOR_ROOT}/test/db.ini -t spidermonkey -s testandroid -o ./auto_sqlite_bindings

```

 请注意 题主只修改了2个地方 一个指定db.ini 是generator.py 的入参   一个指定输出目录  -o ./auto_sqlite_bindings


 8,执行db.sh文件


 如果报错  
                 Fatal Error: NDK r9b must be required! 你可以手动export下  例如 export NDK_ROOT=${NDK r9b的目录}TranslationUnitLoadError: Error parsing translation unit.请检查ini文件 是否路径错误等等
    
 9,如无错误 那么好 应该已经生成了JSB的文件了  你应该会看到下图  
名字的信息 取决于你在db.ini prefix的定义
          
 
 10,
复制cpp hpp 文件到你的Classes目录下吧 快快

   


 11,注册JSB支持
 11.1 
修改AppDelegate 类 引入 
 #include “autogensqlitebindings.hpp"
 11.2 在AppDelegate 类  applicationDidFinishLaunching()方法中添加注册  注意排队哦
 sc->addRegisterCallback(register_all_autogensqlitebindings); 
       
 12,
OK 现在我们可以在js里面愉快的使用sqlite了 修改 app.js




 
 
 var HelloWorldLayer = cc.Layer.extend({
    sprite:null,
    ctor:function () {
        //////////////////////////////
        // 1. super init first
        this._super();


        //开始执行吧 少年们
        //只有在native才需要进行复制
        if(!cc.sys.isNative){
            cc.log("只能在Native下使用");
            return true;
        }
        this._db = new sql.SQLiteWrapper();
        this._dbPath = this._db.initializing("data.db","res","");


        this._isOpen = this._db.open(this._dbPath);


        cc.log("数据库打开结果:" + this._isOpen?"已打开...":"未打开...");


        if(this._isOpen){
            var st = this._db.statement("select * from equip");


            var ary = ];
            while(st.nextRow()){
                var equipVO = new CEquipVO();
                equipVO.wid = parseInt(st.valueString(0));
                equipVO.name = st.valueString(1);
                equipVO.desc = st.valueString(2);
                equipVO.level = st.valueString(3);
                equipVO.icon = st.valueString(4);
                equipVO.quality = st.valueString(5);
                ary.push(equipVO);
            }


            for(var vo in ary){
                cc.log("equipData:" + ary.toString());
            }
        }
        return true;
    }
});


var HelloWorldScene = cc.Scene.extend({
    onEnter:function () {
        this._super();
        var layer = new HelloWorldLayer();
        this.addChild(layer);
    }
});


var CEquipVO = cc.Class.extend({
    wid:null,//like 10000001
    name:null,//like 银票
    level:null,//like 1
    type:null,//like 1
    price:null,//like 200
    stackCount:null,//like 99
    bind:null,//like 1
    desc:null,//like 加银两
    quality:null,//like 1
    icon:null,//like item/article/10000001.png
    toString:function(){
        return this.wid + " " + this.name + " " + this.level + " " + this.desc + " " + this.icon;
    }
});
 
```



 13,在IOS虚拟机上跑下吧 你能看到日志输出了哦





后语:




 虽然我们在ios上实现了 但是 在android上 我们还是要进行修改




 
1,修改 ${PROJECT}/frameworks/runtime-src/proj.android/jni/Android.mk文件
 
 LOCAL_SRC_FILES := hellojavascript/main.cpp \
 ../../Classes/sqlite3.c  \
 ../../Classes/SQLiteWrapper.cpp  \
 ../../Classes/autogensqlitebindings.cpp  \
 ../../Classes/AppDelegate.cpp 
 
```

    
2,你通过cocos compile -p android 编译后 使用Eclipse 愉快的调试吧 
  下图是我android上的调试哦
     


 本教程主要是介绍JSB环境的使用 包括后面接入SDK的时候  等等都能跨端使用


      下面是教程源码 您只需自己在本地创建项目 然后根据教程 覆盖资源 
        jsbcenter.zip (4221 KB)

MARK,MARK!!!楼主给力,收藏先。 慢慢看

少年,不来一发PR吗,SQLite的绑定是林顺他们想做还没时间做的事

楼主很给力啊。必须顶一个!!!

— Begin quote from ____

引用第2楼joshua_astray于2014-09-03 16:34发表的 :
少年,不来一发PR吗,SQLite的绑定是林顺他们想做还没时间做的事 http://www.cocoachina.com/bbs/job.php?action=topost&tid=226949&pid=1045474

— End quote

呀,太帅气了。

帮忙来一发github上的PR吧,谢谢。
真的是我们计划了好长时间,还没来得及做的。

这么好的教程,不垒高楼对不起你。

楼主好厉害。。学习了。:867:

楼主威武。。。等这个好久了。。

:3:不错不错…哈哈

补充:

1,添加github教程地址 你可以直接clone下使用 https://github.com/duhaibo0404/jsbcenter

2,如果在mac/windows无法执行批处理 .sh/.bat 因为python组件安装异常 可至https://github.com/duhaibo0404/jsbcenter/tree/master/tools这里安装

   其实就是保证 ${PROJECT}/tools/bindings-generator/generator.py 执行正常 

  参见 https://github.com/duhaibo0404/jsbcenter/tree/master/jsbcenter/tools/bindings-generator 
   1.安装python2.7

   2.安装yaml

   3.安装

Cheetah

   Mac/Win 都一样 

3,一定要是Android
NDK-r9b 在批处理文件里面已经限制了 见下

 <img title = 'tmp6e563818.png' src='http://cdn.cocimg.com/bbs/attachment/Fid_59/59_318982_4871eedd9c98438.png' > 


 如果不想做版本限制 可把这句取消 但是不能保证会不会有其他问题

再来顶一次!!

mark one down

我以前好像也做过这个:7:

楼主,记得PM我你的地址和联系方式,衣服的size,我要给你寄Cocos2d logo的T恤。

— Begin quote from ____

引用第12楼linshun于2014-09-10 16:02发表的 :
楼主,记得PM我你的地址和联系方式,衣服的size,我要给你寄Cocos2d logo的T恤。 http://www.cocoachina.com/bbs/job.php?action=topost&tid=226949&pid=1050176

— End quote

谢谢Sean

请问那我在生成自带的test的时候报错
Errors in parsing headers:

  1. <severity = Warning,
    location = <SourceLocation file None, line 178, column 9>,
    details = “‘WCHAR_MAX’ macro redefined”>
  2. <severity = Fatal,
    location = <SourceLocation file ‘d:/hello/tools/bindings-gener
    ator/test/…/test/simple_test/simple_class.h’, line 4, column 10>,
    details = “‘string’ file not found”>
    ====

更新

升级到3.0 final之后 问题解决…

在win7下自动绑定用楼主生成好的.cpp .hpp api文件夹放到自己工程里面一样的目录,接着手动绑定一样的操作,为什么运行后控制台提示sql没有定义????

LZ威武!!!

mark一下:2::2::2:

有木有windows版的,用的cocos IDE 编译。。。求解

我也是,你问题有没有解决。