怎样把一个自定义的类绑定到JS RUNTIME
2015-07-16 16:39
232 查看
说是原创,其实还是看了网上各种教程。主要看的是这篇:http://www.cocos2d-x.org/docs/manual/code-ide/function-guides/add-3rd-party-lib/binding-custom-class-to-js/zh
但也整了好几天,有的是因为自己没有看清楚,有的是环境出了问题或者版本可能不一致吧。我用的cocos2dx-js 3.3版本。在此记录一下,希望能给需要的人一些帮助。因为刚开始,自己好多概念性的东西也没有搞明白,只是在js能调到c++代码了。
这个文档的目的是展示一下怎样把一个自定义的cpp类绑定到js runtime。**不涉及jsbinding的细节**。
首先写一个C++类
Utils.h
#include "cocos2d.h"
namespace cocos2d {
class Utils: public cocos2d::Ref{
public:
Utils();
~Utils();
bool init();
std::string helloMsg();
CREATE_FUNC(Utils);
};
} //namespace cocos2d
Utils.cpp
#include "Utils.h"
USING_NS_CC;
Utils::Utils(){
}
Utils::~Utils(){
}
bool Utils::init(){
return true;
}
std::string Utils::helloMsg(){
return "hello from Utils:sayHello";
}
这两个C++文件,放在 /frameworks/js-bindings/cocos2d-x/cocos/my目录下,(这里是在cocos目录下创建了my目录的)
然后把这个my连同Utils.h Utils.cpp文件加到cocos2d_libs.xcodeproj项目里,如下图所示:
一定要注意别加错工程了。
然后在cocos2d_js_bindings.xcodeproj工程里添加源文件路径,如下图所示:
重要的事情在强调一遍,一定要看清楚是在哪个工程下边加的。当初吃了亏啊。
然后这里提前在项目工程的搜索路径中添加绑定文件的路径,如下图所示:
其实我们这里生成的绑定文件就是在auto里。
那么我们现在来生成绑定文件:
在项目下的 /tools/tojs路径下添加cocos2dx_utils.ini文件
[cocos2dx_utils]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = cocos2dx_utils
# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace = cc
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 -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include
-I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/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
cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/my -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/platform/android
cocos_flags = -DANDROID -DCOCOS2D_JAVASCRIPT
cxxgenerator_headers =
# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s
# what headers to parse
headers = %(cocosdir)s/cocos/my/Utils.h
# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^Menu*$".
classes = Utils.*
# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.
skip =
rename_functions =
rename_classes =
# for all class names, should we remove something when registering in the target VM?
remove_prefix =
# 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 = Ref Clonable
# classes that create no constructor
# Set is special and we will use a hand-written constructor
abstract_classes =
# 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 = no
然后修改tools/tojs/genbindings.py文件,添加最后一行。
cmd_args = {'cocos2dx.ini' : ('cocos2d-x', 'jsb_cocos2dx_auto'), \
'cocos2dx_extension.ini' : ('cocos2dx_extension', 'jsb_cocos2dx_extension_auto'), \
'cocos2dx_builder.ini' : ('cocos2dx_builder', 'jsb_cocos2dx_builder_auto'), \
'cocos2dx_ui.ini' : ('cocos2dx_ui', 'jsb_cocos2dx_ui_auto'), \
'cocos2dx_studio.ini' : ('cocos2dx_studio', 'jsb_cocos2dx_studio_auto'), \
'cocos2dx_spine.ini' : ('cocos2dx_spine', 'jsb_cocos2dx_spine_auto'), \
'cocos2dx_utils.ini' : ('cocos2dx_utils', 'jsb_cocos2dx_utils_auto'), \
}
然后运行 tools/tojs/genbindings.py, python genbindings.py命令。之前命令用错了还是少环境的,一顿折腾。
运行完命令之后,就会在/js-bindings/cocos2d-x/plugin/jsbindings/auto目录下生成jsb_cocos2dx_utils_auto.hpp jsb_cocos2dx_utils_auto.cpp文件。
然后把这俩文件添加到cocos2d_js_bindings.xcodeproj工程下边。
添加到工程下边,是指的,在工程target下对应的Build Phases下边能看到
看清是加到哪个工程下边了。
然后就是注册到js
可以看到jsb_cocos2dx_utils_auto.hpp下有方法register_all_cocos2dx_utils,
我们在AppDelegate.cpp里,添加
#include "jsb_cocos2dx_utils_auto.hpp"
sc->addRegisterCallback(register_all_cocos2dx_utils);
就齐活了。
编译之后,接下来就是在js里调用了:
var utilsClass = cc.Utils.create();
var msg = utilsClass.helloMsg();
cc.log("utilsClass's msg is : "+msg);
可以看到输出:
JS: utilsClass's msg is : hello from Utils:sayHello
此时,完工!
自己亲测成功的。虽然好多不明白,但会继续看手动绑定,多了就明白了,至少能调到了。网上教程好多,千万不要总是试,总是半途而废,遇到问题要多想想解决办法,要不然到头来会浪费很多时间。
但也整了好几天,有的是因为自己没有看清楚,有的是环境出了问题或者版本可能不一致吧。我用的cocos2dx-js 3.3版本。在此记录一下,希望能给需要的人一些帮助。因为刚开始,自己好多概念性的东西也没有搞明白,只是在js能调到c++代码了。
这个文档的目的是展示一下怎样把一个自定义的cpp类绑定到js runtime。**不涉及jsbinding的细节**。
首先写一个C++类
Utils.h
#include "cocos2d.h"
namespace cocos2d {
class Utils: public cocos2d::Ref{
public:
Utils();
~Utils();
bool init();
std::string helloMsg();
CREATE_FUNC(Utils);
};
} //namespace cocos2d
Utils.cpp
#include "Utils.h"
USING_NS_CC;
Utils::Utils(){
}
Utils::~Utils(){
}
bool Utils::init(){
return true;
}
std::string Utils::helloMsg(){
return "hello from Utils:sayHello";
}
这两个C++文件,放在 /frameworks/js-bindings/cocos2d-x/cocos/my目录下,(这里是在cocos目录下创建了my目录的)
然后把这个my连同Utils.h Utils.cpp文件加到cocos2d_libs.xcodeproj项目里,如下图所示:
一定要注意别加错工程了。
然后在cocos2d_js_bindings.xcodeproj工程里添加源文件路径,如下图所示:
重要的事情在强调一遍,一定要看清楚是在哪个工程下边加的。当初吃了亏啊。
然后这里提前在项目工程的搜索路径中添加绑定文件的路径,如下图所示:
其实我们这里生成的绑定文件就是在auto里。
那么我们现在来生成绑定文件:
在项目下的 /tools/tojs路径下添加cocos2dx_utils.ini文件
[cocos2dx_utils]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = cocos2dx_utils
# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace = cc
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 -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include
-I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/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
cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/my -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/platform/android
cocos_flags = -DANDROID -DCOCOS2D_JAVASCRIPT
cxxgenerator_headers =
# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s
# what headers to parse
headers = %(cocosdir)s/cocos/my/Utils.h
# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^Menu*$".
classes = Utils.*
# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.
skip =
rename_functions =
rename_classes =
# for all class names, should we remove something when registering in the target VM?
remove_prefix =
# 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 = Ref Clonable
# classes that create no constructor
# Set is special and we will use a hand-written constructor
abstract_classes =
# 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 = no
然后修改tools/tojs/genbindings.py文件,添加最后一行。
cmd_args = {'cocos2dx.ini' : ('cocos2d-x', 'jsb_cocos2dx_auto'), \
'cocos2dx_extension.ini' : ('cocos2dx_extension', 'jsb_cocos2dx_extension_auto'), \
'cocos2dx_builder.ini' : ('cocos2dx_builder', 'jsb_cocos2dx_builder_auto'), \
'cocos2dx_ui.ini' : ('cocos2dx_ui', 'jsb_cocos2dx_ui_auto'), \
'cocos2dx_studio.ini' : ('cocos2dx_studio', 'jsb_cocos2dx_studio_auto'), \
'cocos2dx_spine.ini' : ('cocos2dx_spine', 'jsb_cocos2dx_spine_auto'), \
'cocos2dx_utils.ini' : ('cocos2dx_utils', 'jsb_cocos2dx_utils_auto'), \
}
然后运行 tools/tojs/genbindings.py, python genbindings.py命令。之前命令用错了还是少环境的,一顿折腾。
运行完命令之后,就会在/js-bindings/cocos2d-x/plugin/jsbindings/auto目录下生成jsb_cocos2dx_utils_auto.hpp jsb_cocos2dx_utils_auto.cpp文件。
然后把这俩文件添加到cocos2d_js_bindings.xcodeproj工程下边。
添加到工程下边,是指的,在工程target下对应的Build Phases下边能看到
看清是加到哪个工程下边了。
然后就是注册到js
可以看到jsb_cocos2dx_utils_auto.hpp下有方法register_all_cocos2dx_utils,
我们在AppDelegate.cpp里,添加
#include "jsb_cocos2dx_utils_auto.hpp"
sc->addRegisterCallback(register_all_cocos2dx_utils);
就齐活了。
编译之后,接下来就是在js里调用了:
var utilsClass = cc.Utils.create();
var msg = utilsClass.helloMsg();
cc.log("utilsClass's msg is : "+msg);
可以看到输出:
JS: utilsClass's msg is : hello from Utils:sayHello
此时,完工!
自己亲测成功的。虽然好多不明白,但会继续看手动绑定,多了就明白了,至少能调到了。网上教程好多,千万不要总是试,总是半途而废,遇到问题要多想想解决办法,要不然到头来会浪费很多时间。
相关文章推荐
- js cookie清除(解决不同页面下清除失败)
- 瀑布流布局的几种实现
- js offsetHeight offsetWidth 解说
- JS校验金额格式的正则表达式
- javascript的位操作、整数、二进制
- 《JavaScript设计模式与开发实践》读书笔记之代理模式
- doT js模板入门 3
- 学习Javascript闭包(Closure)
- sprigmvc中jsp页面读取js文件
- Javascript作用域问题的构造函数的变量
- JSP编程的基本知识
- 让Json和Model相处的融洽点
- nsjsonserialization 三个枚举值的用法
- js 图片懒加载
- JS组装 HTML片段 列表 ul li
- Js获取当前日期时间及其它操作
- JS判断手机访问
- js整理
- 《JavaScript设计模式与开发实践》读书笔记之策略模式
- AJAX样例及返回值json解析