如何将c++绑定至javascript

 我来答
可以叫我表哥
推荐于2018-04-11 · 知道合伙人数码行家
可以叫我表哥
知道合伙人数码行家
采纳数:25897 获赞数:1464978
2010年毕业于北京化工大学北方学院计算机科学与技术专业毕业,学士学位,工程电子技术行业4年从业经验。

向TA提问 私信TA
展开全部
下载绑定生成器,本机路径/Users/iven/Dev/bindings-generator
为了在Mac OS X中安装运行MacPort端口,系统必须要已经安装苹果的“Command Line Developer Tools”(命令行开发者工具)。Xcode 4及以后版本的用户首先需要通过启动或运行Xcode接受Xcode EULA。

xcodebuild -license
下载安装MacPort
注意:如果是Homebrew用户,应该先卸载Homebrew。因为Homebrew不兼容MacPort。
同时执行MacPort的“selfupdate”命令以确保安装最新的发布版本。

sudo port -v selfupdate
当更新完成之后,使用MacPort在命令行中安装python依赖(dependencies)

sudo port install python27 py27-yaml py27-cheetah
你会看到如下所示:

下载llvm-3.3,解压至$HOME/bin目录。如果没有bin目录,请创建一个bin目录,将未解压的ZIP压缩包重命名为“clang+llvm-3.3”。
最后目录如下所示:/Users/guanghui/bin/clang+llvm-3.3(guanhui是本机的主目录名字)

样本代码

绑定生成器资源库中包括一个样本测试用例。打开bindings-generator/test/simple_test文件夹。

配置

根据自己的环境个性化设置“test/userconf.ini”和“test/user.cfg”文件。
注意:应该移除后缀为“.sample”的文件如“user.cfg.sample”和“userconf.ini.sample”

[DEFAULT]
androidndkdir=/Users/iven/Dev/android-ndk-r8c
clangllvmdir=/Users/iven/Dev/clang+llvm-3.1-x86_64-apple-darwin11
cxxgeneratordir=/Users/iven/Dev/bindings-generator-master
user.cfg配置如下所示

PYTHON_BIN=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin/ python2.7
运行测试样本

./test.sh
如果环境设置正确,你会看到如下所示:

Errors in parsing headers:
1. <severity = Warning,
location =<SourceLocation file None, line 0, column 0>,
details = "argument unusedduring compilation: '-nostdinc++'">
不用担心这个警告,你已完成运行,测试用例会创建一个包含3个文件的“simple_test_bindings”目录。

一个绑定类的.hpp头文件

一个实现绑定类的.cpp文件

一个介绍如何(从Java脚本)调用C++类暴露方法的.js文件。

运行测试

Create a JS base Cocos2d-x project. 创建基于JS的Cocos2d-x项目

将“simple_Test folder”文件夹和“simple_test_binding”文件夹添加到项目中

修改“autogentestbindings.cpp”中的注册函数如下:

void register_all_autogentestbindings(JSContext* cx, JSObject* obj) {
jsval nsval;
JSObject *ns;
JS_GetProperty(cx, obj, "ts",&nsval);
if (nsval == JSVAL_VOID) {
ns = JS_NewObject(cx, NULL, NULL, NULL);
nsval = OBJECT_TO_JSVAL(ns);
JS_SetProperty(cx, obj, "ts",&nsval);
} else {
JS_ValueToObject(cx,nsval, &ns);
}
obj = ns;
js_register_autogentestbindings_SimpleNativeClass(cx, obj);
}
注意:如果你将“ts”添加到“test.ini”文件中的“target_namespace”变量里,便会自动生成代码。无需修改。

target_namespace =ts
在“AppDelegate”中注册

包含头文件“autogentestbindings.hpp”然后注册回调函数:

sc->addRegisterCallback(register_all_autogentestbindings);
在“hello.js”文件适当地方增加以下代码。本机将“init f”函数放在第一个场景。

var myClass=new ts.SimpleNativeClass();
var myStr=myClass.returnsACString();
var label = cc.LabelTTF.create(myStr, "Helvetica", 20.0);
限制

绑定生成器存在以下两个限制

自变量数字参数无法工作,所以需要手动编写包装器
代表类无法工作,所以需要手动绑定,详见下一部分。
手动 JSB 绑定

本指南将介绍利用Cocos2d-x 2.14模板如何在自己的项目中实现JSB绑定。
首先用Cocos2d-js模板创建项目。其次,我们会介绍如何一步一步从JS调用本地函数。最后你便会学会如何从本地代码调用JS代码了。
现在让我们开始!本机使用的Mac OS X作为开发环境。

步骤1. 用Cocos2dx-js模板创建新项目,同时新建一个即将绑定至JS的C++类。

将项目命名为“JSBinding”然后点击“Next”、“ Create”

新建一个类然后实现这个类,等会再将其绑定至JS。
按“command+N”新建一个C++类并命名为“JSBinding”,路径为“OS X\C and C++\C++ Class”。

将以下代码添加到“JSBinding.h”文件中。

#include "cocos2d.h"
#include "ScriptingCore.h"
// Define a namespace to manage your code and make your code clearly
namespace JSB {
class JSBinding: public cocos2d::CCObject
{
public:
static cocos2d::CCScene* scene();
virtual bool init();
CREATE_FUNC(JSBinding);
void functionTest();
};
}
现在实现JSBinding.cpp中的类。如下所示:

bool JSB::JSBinding::init(){
bool bRef = false;
do{
cocos2d::CCLog("JSB init...");
bRef = true;
} while (0);
return bRef;
}
void JSB::JSBinding::functionTest(){
cocos2d::CCLog("Function test...");
}
步骤2. 将C++代码绑定至Java脚本代码

按“command+N”新建C++类,然后命名“JSB_AUTO”路径“OS X\C and C++\C++ Class”。

往“JSB_AUTO.h”文件中增加一些代码

#include "jsapi.h"
#include "jsfriendapi.h"
#include "ScriptingCore.h"
#include "JSBinding.h"
void register_all(JSContext* cx, JSObject* obj);
然后注意“JSB_AUTO.cpp”的实现。

#include "jsapi.h"
#include "jsfriendapi.h"
#include "ScriptingCore.h"
#include "JSBinding.h"
void register_all(JSContext* cx, JSObject* obj);
然后注意“JSB_AUTO.cpp”的实现。

#include "cocos2d.h"
#include "cocos2d_specifics.hpp"
// Binding specific object by defining JSClass
JSClass* jsb_class;
JSObject* jsb_prototype;
// This function is mapping the function “functionTest” in “JSBinding.cpp”
JSBool js_functionTest(JSContext* cx, uint32_t argc, jsval* vp){
JSBool ok = JS_TRUE;
JSObject* obj = NULL;
JSB::JSBinding* cobj = NULL;
obj = JS_THIS_OBJECT(cx, vp);
js_proxy_t* proxy = jsb_get_js_proxy(obj);
cobj = (JSB::JSBinding* )(proxy ? proxy->ptr : NULL);
JSB_PRECONDITION2(cobj, cx, JS_FALSE, "Invalid Native Object");
if (argc == 0) {
cobj->functionTest();
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return ok;
}
JS_ReportError(cx, "Wrong number of arguments");
return JS_FALSE;
}
JSBool js_constructor(JSContext* cx, uint32_t argc, jsval* vp){
cocos2d::CCLog("JS Constructor...");
if (argc == 0) {
JSB::JSBinding* cobj = new JSB::JSBinding();
cocos2d::CCObject* ccobj = dynamic_cast<cocos2d::CCObject*>(cobj);
if (ccobj) {
ccobj->autorelease();
}
TypeTest<JSB::JSBinding> t;
js_type_class_t* typeClass;
uint32_t typeId = t.s_id();
HASH_FIND_INT(_js_global_type_ht, &typeId, typeClass);
assert(typeClass);
JSObject* obj = JS_NewObject(cx, typeClass->jsclass, typeClass->proto, typeClass->parentProto);
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
js_proxy_t* p = jsb_new_proxy(cobj, obj);
JS_AddNamedObjectRoot(cx, &p->obj, "JSB::JSBinding");
return JS_TRUE;
}
JS_ReportError(cx, "Wrong number of arguments: %d, was expecting: %d", argc, 0);
return JS_FALSE;
}
// This function is mapping the function “create” when using JavaScript code
JSBool js_create(JSContext* cx, uint32_t argc, jsval* vp){
cocos2d::CCLog("js is creating...");
if (argc == 0) {
JSB::JSBinding* ret = JSB::JSBinding::create();
jsval jsret;
do{
if (ret) {
js_proxy_t* proxy = js_get_or_create_proxy<JSB::JSBinding>(cx, ret);
jsret = OBJECT_TO_JSVAL(proxy->obj);
}
else{
jsret = JSVAL_NULL;
}
} while(0);
JS_SET_RVAL(cx, vp, jsret);
return JS_FALSE;
}
JS_ReportError(cx, "Wrong number of arguments");
return JS_FALSE;
}
void js_finalize(JSFreeOp* fop, JSObject* obj){
CCLOGINFO("JSBindings: finallizing JS object %p JSB", obj);
}
// Binding JSB type
void js_register(JSContext* cx, JSObject* global){
jsb_class = (JSClass *)calloc(1, sizeof(JSClass));
jsb_class->name = "JSBinding";
jsb_class->addProperty = JS_PropertyStub;
jsb_class->delProperty = JS_PropertyStub;
jsb_class->getProperty = JS_PropertyStub;
jsb_class->setProperty = JS_StrictPropertyStub;
jsb_class->enumerate = JS_EnumerateStub;
jsb_class->resolve = JS_ResolveStub;
jsb_class->convert = JS_ConvertStub;
jsb_class->finalize = js_finalize;
jsb_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);
static JSPropertySpec properties[] = {
{0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER}
};
// Binding functionTest function
static JSFunctionSpec funcs[] = {
JS_FN("functionTest", js_functionTest, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_FS_END
};
// Binding create() function
static JSFunctionSpec st_funcs[] = {
JS_FN("create", js_create, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_FS_END
};
// Binding constructor function and prototype
jsb_prototype = JS_InitClass(
cx, global,
NULL,
jsb_class,
js_constructor, 0,
properties,
funcs,
NULL,
st_funcs);
JSBool found;
JS_SetPropertyAttributes(cx, global, "JSB", JSPROP_ENUMERATE | JSPROP_READONLY, &found);
TypeTest<JSB::JSBinding> t;
js_type_class_t* p;
uint32_t typeId = t.s_id();
HASH_FIND_INT(_js_global_type_ht, &typeId, p);
if (!p) {
p = (js_type_class_t* )malloc(sizeof(_js_global_type_ht));
p->type = typeId;
p->jsclass = jsb_class;
p->proto = jsb_prototype;
p->parentProto = NULL;
HASH_ADD_INT(_js_global_type_ht, type, p);
}
}
// Binding JSB namespace so in JavaScript code JSB namespce can be recognized
void register_all(JSContext* cx, JSObject* obj){
jsval nsval;
JSObject* ns;
JS_GetProperty(cx, obj, "JS", &nsval);
if (nsval == JSVAL_VOID) {
ns = JS_NewObject(cx, NULL, NULL, NULL);
nsval = OBJECT_TO_JSVAL(ns);
JS_SetProperty(cx, obj, "JSB", &nsval);
}
else{
JS_ValueToObject(cx, nsval, &ns);
}
obj = ns;
js_register(cx, obj);
}
现在已经完成了大部分工作,但是我们需要在“SpiderMonkey”进行注册。
打开“AppDelegate.cpp”增加以下代码

ScriptingCore* sc = ScriptingCore::getInstance();
sc->addRegisterCallback(register_all); //add this line
步骤3. 内存管理
在register_all函数前增加两个新函数。

JSBool JSB_cocos2dx_retain(JSContext* cx, uint32_t argc, jsval *vp){
JSObject* thisObj = JS_THIS_OBJECT(cx, vp);
if (thisObj) {
js_proxy_t* proxy = jsb_get_js_proxy(thisObj);
if (proxy) {
((CCObject* )proxy->ptr)->retain();
CCLog("Retain succeed!");
return JS_TRUE;
}
}
JS_ReportError(cx, "Invaild native object");
return JS_FALSE;
}
JSBool JSB_cocos2dx_release(JSContext* cx, uint32_t argc, jsval *vp){
JSObject* thisObj = JS_THIS_OBJECT(cx, vp);
if (thisObj) {
js_proxy_t* proxy = jsb_get_js_proxy(thisObj);
if (proxy) {
((CCObject* )proxy->ptr)->release();
CCLog("Release succeed!");
return JS_TRUE;
}
}
JS_ReportError(cx, "Invaild native object");
return JS_FALSE;
}
在register_all函数中增加以下代码:

JS_DefineFunction(cx, jsb_prototype, "retain", JSB_cocos2dx_retain, 0, JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(cx, jsb_prototype, "retain", JSB_cocos2dx_release, 0, JSPROP_READONLY | JSPROP_PERMANENT);
步骤4. 使用C++代码回调Java脚本代码
在C++代码回调Java脚本代码之前增加一些代码至“hello.js”文件。

var testJSB = new JSB.JSBinding();
testJSB.callback = function(i, j){
log("JSB Callback" + i + j);
};
然后打开“JSBinding.cpp”在“functionTest”中增加一些代码。

js_proxy_t* p = jsb_get_native_proxy(this);
jsval retval;
jsval v[] = {
v[0] = UINT_TO_JSVAL(32),
v[1] = UINT_TO_JSVAL(88)
};
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj),
"callback", 2, v, &retval);
使用“executeFunctionWithOwner()”函数简化函数调用程序
步骤5. 绑定测试
在“hello.js”文件中增加以下代码。

var testJSB = new JSB.JSBinding();
testJSB.retain();
testJSB.functionTest();
testJSB.release();
步骤6. 现在取出(check out)项目
如果你的绑定程序正确无误,将会在调试窗口看到如下界面:

恭喜你成功将JS绑定至本地代码!
huanglenzhi
推荐于2016-09-09 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
采纳数:117538 获赞数:517184
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。

向TA提问 私信TA
展开全部
下载绑定生成器,本机路径/Users/iven/Dev/bindings-generator
为了在Mac OS X中安装运行MacPort端口,系统必须要已经安装苹果的“Command Line Developer Tools”(命令行开发者工具)。Xcode 4及以后版本的用户首先需要通过启动或运行Xcode接受Xcode EULA。

xcodebuild -license
下载安装MacPort
注意:如果是Homebrew用户,应该先卸载Homebrew。因为Homebrew不兼容MacPort。
同时执行MacPort的“selfupdate”命令以确保安装最新的发布版本。

sudo port -v selfupdate
当更新完成之后,使用MacPort在命令行中安装python依赖(dependencies)

sudo port install python27 py27-yaml py27-cheetah
你会看到如下所示:

下载llvm-3.3,解压至$HOME/bin目录。如果没有bin目录,请创建一个bin目录,将未解压的ZIP压缩包重命名为“clang+llvm-3.3”。
最后目录如下所示:/Users/guanghui/bin/clang+llvm-3.3(guanhui是本机的主目录名字)

样本代码

绑定生成器资源库中包括一个样本测试用例。打开bindings-generator/test/simple_test文件夹。

配置

根据自己的环境个性化设置“test/userconf.ini”和“test/user.cfg”文件。
注意:应该移除后缀为“.sample”的文件如“user.cfg.sample”和“userconf.ini.sample”

[DEFAULT]
androidndkdir=/Users/iven/Dev/android-ndk-r8c
clangllvmdir=/Users/iven/Dev/clang+llvm-3.1-x86_64-apple-darwin11
cxxgeneratordir=/Users/iven/Dev/bindings-generator-master
user.cfg配置如下所示

PYTHON_BIN=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin/ python2.7
运行测试样本

./test.sh
如果环境设置正确,你会看到如下所示:

Errors in parsing headers:
1. <severity = Warning,
location =<SourceLocation file None, line 0, column 0>,
details = "argument unusedduring compilation: '-nostdinc++'">
不用担心这个警告,你已完成运行,测试用例会创建一个包含3个文件的“simple_test_bindings”目录。

一个绑定类的.hpp头文件

一个实现绑定类的.cpp文件

一个介绍如何(从Java脚本)调用C++类暴露方法的.js文件。

运行测试

Create a JS base Cocos2d-x project. 创建基于JS的Cocos2d-x项目

将“simple_Test folder”文件夹和“simple_test_binding”文件夹添加到项目中

修改“autogentestbindings.cpp”中的注册函数如下:

void register_all_autogentestbindings(JSContext* cx, JSObject* obj) {
jsval nsval;
JSObject *ns;
JS_GetProperty(cx, obj, "ts",&nsval);
if (nsval == JSVAL_VOID) {
ns = JS_NewObject(cx, NULL, NULL, NULL);
nsval = OBJECT_TO_JSVAL(ns);
JS_SetProperty(cx, obj, "ts",&nsval);
} else {
JS_ValueToObject(cx,nsval, &ns);
}
obj = ns;
js_register_autogentestbindings_SimpleNativeClass(cx, obj);
}
注意:如果你将“ts”添加到“test.ini”文件中的“target_namespace”变量里,便会自动生成代码。无需修改。

target_namespace =ts
在“AppDelegate”中注册

包含头文件“autogentestbindings.hpp”然后注册回调函数:

sc->addRegisterCallback(register_all_autogentestbindings);
在“hello.js”文件适当地方增加以下代码。本机将“init f”函数放在第一个场景。

var myClass=new ts.SimpleNativeClass();
var myStr=myClass.returnsACString();
var label = cc.LabelTTF.create(myStr, "Helvetica", 20.0);
限制

绑定生成器存在以下两个限制

自变量数字参数无法工作,所以需要手动编写包装器
代表类无法工作,所以需要手动绑定,详见下一部分。
手动 JSB 绑定

本指南将介绍利用Cocos2d-x 2.14模板如何在自己的项目中实现JSB绑定。
首先用Cocos2d-js模板创建项目。其次,我们会介绍如何一步一步从JS调用本地函数。最后你便会学会如何从本地代码调用JS代码了。
现在让我们开始!本机使用的Mac OS X作为开发环境。

步骤1. 用Cocos2dx-js模板创建新项目,同时新建一个即将绑定至JS的C++类。

将项目命名为“JSBinding”然后点击“Next”、“ Create”

新建一个类然后实现这个类,等会再将其绑定至JS。
按“command+N”新建一个C++类并命名为“JSBinding”,路径为“OS X\C and C++\C++ Class”。

将以下代码添加到“JSBinding.h”文件中。

#include "cocos2d.h"
#include "ScriptingCore.h"
// Define a namespace to manage your code and make your code clearly
namespace JSB {
class JSBinding: public cocos2d::CCObject
{
public:
static cocos2d::CCScene* scene();
virtual bool init();
CREATE_FUNC(JSBinding);
void functionTest();
};
}
现在实现JSBinding.cpp中的类。如下所示:

bool JSB::JSBinding::init(){
bool bRef = false;
do{
cocos2d::CCLog("JSB init...");
bRef = true;
} while (0);
return bRef;
}
void JSB::JSBinding::functionTest(){
cocos2d::CCLog("Function test...");
}
步骤2. 将C++代码绑定至Java脚本代码

按“command+N”新建C++类,然后命名“JSB_AUTO”路径“OS X\C and C++\C++ Class”。

往“JSB_AUTO.h”文件中增加一些代码

#include "jsapi.h"
#include "jsfriendapi.h"
#include "ScriptingCore.h"
#include "JSBinding.h"
void register_all(JSContext* cx, JSObject* obj);
然后注意“JSB_AUTO.cpp”的实现。

#include "jsapi.h"
#include "jsfriendapi.h"
#include "ScriptingCore.h"
#include "JSBinding.h"
void register_all(JSContext* cx, JSObject* obj);
然后注意“JSB_AUTO.cpp”的实现。

#include "cocos2d.h"
#include "cocos2d_specifics.hpp"
// Binding specific object by defining JSClass
JSClass* jsb_class;
JSObject* jsb_prototype;
// This function is mapping the function “functionTest” in “JSBinding.cpp”
JSBool js_functionTest(JSContext* cx, uint32_t argc, jsval* vp){
JSBool ok = JS_TRUE;
JSObject* obj = NULL;
JSB::JSBinding* cobj = NULL;
obj = JS_THIS_OBJECT(cx, vp);
js_proxy_t* proxy = jsb_get_js_proxy(obj);
cobj = (JSB::JSBinding* )(proxy ? proxy->ptr : NULL);
JSB_PRECONDITION2(cobj, cx, JS_FALSE, "Invalid Native Object");
if (argc == 0) {
cobj->functionTest();
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return ok;
}
JS_ReportError(cx, "Wrong number of arguments");
return JS_FALSE;
}
JSBool js_constructor(JSContext* cx, uint32_t argc, jsval* vp){
cocos2d::CCLog("JS Constructor...");
if (argc == 0) {
JSB::JSBinding* cobj = new JSB::JSBinding();
cocos2d::CCObject* ccobj = dynamic_cast<cocos2d::CCObject*>(cobj);
if (ccobj) {
ccobj->autorelease();
}
TypeTest<JSB::JSBinding> t;
js_type_class_t* typeClass;
uint32_t typeId = t.s_id();
HASH_FIND_INT(_js_global_type_ht, &typeId, typeClass);
assert(typeClass);
JSObject* obj = JS_NewObject(cx, typeClass->jsclass, typeClass->proto, typeClass->parentProto);
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
js_proxy_t* p = jsb_new_proxy(cobj, obj);
JS_AddNamedObjectRoot(cx, &p->obj, "JSB::JSBinding");
return JS_TRUE;
}
JS_ReportError(cx, "Wrong number of arguments: %d, was expecting: %d", argc, 0);
return JS_FALSE;
}
// This function is mapping the function “create” when using JavaScript code
JSBool js_create(JSContext* cx, uint32_t argc, jsval* vp){
cocos2d::CCLog("js is creating...");
if (argc == 0) {
JSB::JSBinding* ret = JSB::JSBinding::create();
jsval jsret;
do{
if (ret) {
js_proxy_t* proxy = js_get_or_create_proxy<JSB::JSBinding>(cx, ret);
jsret = OBJECT_TO_JSVAL(proxy->obj);
}
else{
jsret = JSVAL_NULL;
}
} while(0);
JS_SET_RVAL(cx, vp, jsret);
return JS_FALSE;
}
JS_ReportError(cx, "Wrong number of arguments");
return JS_FALSE;
}
void js_finalize(JSFreeOp* fop, JSObject* obj){
CCLOGINFO("JSBindings: finallizing JS object %p JSB", obj);
}
// Binding JSB type
void js_register(JSContext* cx, JSObject* global){
jsb_class = (JSClass *)calloc(1, sizeof(JSClass));
jsb_class->name = "JSBinding";
jsb_class->addProperty = JS_PropertyStub;
jsb_class->delProperty = JS_PropertyStub;
jsb_class->getProperty = JS_PropertyStub;
jsb_class->setProperty = JS_StrictPropertyStub;
jsb_class->enumerate = JS_EnumerateStub;
jsb_class->resolve = JS_ResolveStub;
jsb_class->convert = JS_ConvertStub;
jsb_class->finalize = js_finalize;
jsb_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);
static JSPropertySpec properties[] = {
{0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER}
};
// Binding functionTest function
static JSFunctionSpec funcs[] = {
JS_FN("functionTest", js_functionTest, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_FS_END
};
// Binding create() function
static JSFunctionSpec st_funcs[] = {
JS_FN("create", js_create, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_FS_END
};
// Binding constructor function and prototype
jsb_prototype = JS_InitClass(
cx, global,
NULL,
jsb_class,
js_constructor, 0,
properties,
funcs,
NULL,
st_funcs);
JSBool found;
JS_SetPropertyAttributes(cx, global, "JSB", JSPROP_ENUMERATE | JSPROP_READONLY, &found);
TypeTest<JSB::JSBinding> t;
js_type_class_t* p;
uint32_t typeId = t.s_id();
HASH_FIND_INT(_js_global_type_ht, &typeId, p);
if (!p) {
p = (js_type_class_t* )malloc(sizeof(_js_global_type_ht));
p->type = typeId;
p->jsclass = jsb_class;
p->proto = jsb_prototype;
p->parentProto = NULL;
HASH_ADD_INT(_js_global_type_ht, type, p);
}
}
// Binding JSB namespace so in JavaScript code JSB namespce can be recognized
void register_all(JSContext* cx, JSObject* obj){
jsval nsval;
JSObject* ns;
JS_GetProperty(cx, obj, "JS", &nsval);
if (nsval == JSVAL_VOID) {
ns = JS_NewObject(cx, NULL, NULL, NULL);
nsval = OBJECT_TO_JSVAL(ns);
JS_SetProperty(cx, obj, "JSB", &nsval);
}
else{
JS_ValueToObject(cx, nsval, &ns);
}
obj = ns;
js_register(cx, obj);
}
现在已经完成了大部分工作,但是我们需要在“SpiderMonkey”进行注册。
打开“AppDelegate.cpp”增加以下代码

ScriptingCore* sc = ScriptingCore::getInstance();
sc->addRegisterCallback(register_all); //add this line
步骤3. 内存管理
在register_all函数前增加两个新函数。

JSBool JSB_cocos2dx_retain(JSContext* cx, uint32_t argc, jsval *vp){
JSObject* thisObj = JS_THIS_OBJECT(cx, vp);
if (thisObj) {
js_proxy_t* proxy = jsb_get_js_proxy(thisObj);
if (proxy) {
((CCObject* )proxy->ptr)->retain();
CCLog("Retain succeed!");
return JS_TRUE;
}
}
JS_ReportError(cx, "Invaild native object");
return JS_FALSE;
}
JSBool JSB_cocos2dx_release(JSContext* cx, uint32_t argc, jsval *vp){
JSObject* thisObj = JS_THIS_OBJECT(cx, vp);
if (thisObj) {
js_proxy_t* proxy = jsb_get_js_proxy(thisObj);
if (proxy) {
((CCObject* )proxy->ptr)->release();
CCLog("Release succeed!");
return JS_TRUE;
}
}
JS_ReportError(cx, "Invaild native object");
return JS_FALSE;
}
在register_all函数中增加以下代码:

JS_DefineFunction(cx, jsb_prototype, "retain", JSB_cocos2dx_retain, 0, JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(cx, jsb_prototype, "retain", JSB_cocos2dx_release, 0, JSPROP_READONLY | JSPROP_PERMANENT);
步骤4. 使用C++代码回调Java脚本代码
在C++代码回调Java脚本代码之前增加一些代码至“hello.js”文件。

var testJSB = new JSB.JSBinding();
testJSB.callback = function(i, j){
log("JSB Callback" + i + j);
};
然后打开“JSBinding.cpp”在“functionTest”中增加一些代码。

js_proxy_t* p = jsb_get_native_proxy(this);
jsval retval;
jsval v[] = {
v[0] = UINT_TO_JSVAL(32),
v[1] = UINT_TO_JSVAL(88)
};
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj),
"callback", 2, v, &retval);
使用“executeFunctionWithOwner()”函数简化函数调用程序
步骤5. 绑定测试
在“hello.js”文件中增加以下代码。

var testJSB = new JSB.JSBinding();
testJSB.retain();
testJSB.functionTest();
testJSB.release();
步骤6. 现在取出(check out)项目
如果你的绑定程序正确无误,将会在调试窗口看到如下界面:

恭喜你成功将JS绑定至本地代码!
本回答被提问者和网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
kyotrue
2015-01-08 · TA获得超过1.5万个赞
知道大有可为答主
回答量:2.3万
采纳率:75%
帮助的人:6777万
展开全部
只能做成OCX控件供JS调用。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式