Cocos Creator 手动绑定不完全手册
官方 JSB 2.0 说明文档
http://docs.cocos.com/creator/manual/zh/advanced-topics/jsb/JSB2.0-learning.html
本文只补齐文档中缺少的实操部分,具体代码是什么意思请参考文档
废话不多说,由于本例子在 iOS 真机上测试的,所以只构建 xcode 工程,Android 同理
Creator v2.0.1
MacOS, XCode
Github: https://github.com/shpz/CocosJSBExample
交流群: 850993054
Step 1
首先构建 xcode 工程,如图所示
记得把调试模式钩上方便测试

Step 2
打开构建好的 xcode,长这样

然后依次点开 cocos2d_libs.xcodeproj/jsbindings/manual
## Step 3
在这里新建一个 jsb_test.hpp 一个 jsb_test.cpp,把以下内容依次复制进去
// jsb step 3
// jsb_test.hpp
#pragma once
namespace se {
class Object;
}
bool js_register_jsbTest_jsbTest(se::Object* obj);
// jsb step 3
// jsb_test.cpp
#include "jsb_test.hpp"
#include "cocos2d.h"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
USING_NS_CC;
static bool jsb_test_log(se::State& s)
{
CCLOG("jsb_test_log, run this!");
return true;
}
SE_BIND_FUNC(jsb_test_log)
bool js_register_jsbTest_jsbTest(se::Object* global)
{
global->defineFunction("jsb_test_log", _SE(jsb_test_log));
return true;
}
然后再新建一个 jsb_class_test.hpp 一个 jsb_class_test.cpp,把以下内容依次复制进去
// jsb step 3
// jsb_class_test.hpp
namespace se {
class Object;
class Class;
}
bool js_register_ns_SomeClass(se::Object* obj);
// jsb step 3
// jsb_class_test.cpp
#include "jsb_class_test.hpp"
#include "cocos2d.h"
#include "SeApi.h"
#include "jsb_classtype.hpp"
USING_NS_CC;
static se::Object* __jsb_ns_SomeClass_proto = nullptr;
static se::Class* __jsb_ns_SomeClass_class = nullptr;
namespace ns {
class SomeClass
{
public:
SomeClass()
: xxx(0)
{}
void foo() {
printf("SomeClass::foo\n");
}
static void static_func() {
printf("SomeClass::static_func\n");
}
void setCallback(const std::function<void(int)>& cb) {
_cb = cb;
if (_cb != nullptr)
{
printf("setCallback(cb)\n");
}
else
{
printf("setCallback(nullptr)\n");
}
}
int xxx;
private:
std::function<void(int)> _cb;
};
}
static bool js_SomeClass_finalize(se::State& s)
{
ns::SomeClass* cobj = (ns::SomeClass*)s.nativeThisObject();
delete cobj;
return true;
}
SE_BIND_FINALIZE_FUNC(js_SomeClass_finalize)
static bool js_SomeClass_constructor(se::State& s)
{
ns::SomeClass* cobj = new ns::SomeClass();
s.thisObject()->setPrivateData(cobj);
return true;
}
SE_BIND_CTOR(js_SomeClass_constructor, __jsb_ns_SomeClass_class, js_SomeClass_finalize)
static bool js_SomeClass_foo(se::State& s)
{
ns::SomeClass* cobj = (ns::SomeClass*)s.nativeThisObject();
cobj->foo();
return true;
}
SE_BIND_FUNC(js_SomeClass_foo)
static bool js_SomeClass_get_xxx(se::State& s)
{
ns::SomeClass* cobj = (ns::SomeClass*)s.nativeThisObject();
s.rval().setInt32(cobj->xxx);
return true;
}
SE_BIND_PROP_GET(js_SomeClass_get_xxx)
static bool js_SomeClass_set_xxx(se::State& s)
{
const auto& args = s.args();
int argc = (int)args.size();
if (argc > 0)
{
ns::SomeClass* cobj = (ns::SomeClass*)s.nativeThisObject();
cobj->xxx = args[0].toInt32();
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 1);
return false;
}
SE_BIND_PROP_SET(js_SomeClass_set_xxx)
static bool js_SomeClass_static_func(se::State& s)
{
ns::SomeClass::static_func();
return true;
}
SE_BIND_FUNC(js_SomeClass_static_func)
bool js_register_ns_SomeClass(se::Object* global)
{
// 保证 namespace 对象存在
se::Value nsVal;
if (!global->getProperty("ns", &nsVal))
{
// 不存在则创建一个 JS 对象,相当于 var ns = {};
se::HandleObject jsobj(se::Object::createPlainObject());
nsVal.setObject(jsobj);
// 将 ns 对象挂载到 global 对象中,名称为 ns
global->setProperty("ns", nsVal);
}
se::Object* ns = nsVal.toObject();
// 创建一个 Class 对象,开发者无需考虑 Class 对象的释放,其交由 ScriptEngine 内部自动处理
auto cls = se::Class::create("SomeClass", ns, nullptr, _SE(js_SomeClass_constructor)); // 如果无构造函数,最后一个参数可传入 nullptr,则这个类在 JS 中无法被 new SomeClass()出来
// 为这个 Class 对象定义成员函数、属性、静态函数、析构函数
cls->defineFunction("foo", _SE(js_SomeClass_foo));
cls->defineProperty("xxx", _SE(js_SomeClass_get_xxx), _SE(js_SomeClass_set_xxx));
cls->defineFinalizeFunction(_SE(js_SomeClass_finalize));
// 注册类型到 JS VirtualMachine 的操作
cls->install();
// JSBClassType 为 Cocos 引擎绑定层封装的类型注册的辅助函数,此函数不属于 ScriptEngine 这层
JSBClassType::registerClass<ns::SomeClass>(cls);
// 保存注册的结果,便于其他地方使用,比如类继承
__jsb_ns_SomeClass_proto = cls->getProto();
__jsb_ns_SomeClass_class = cls;
// 为每个此 Class 实例化出来的对象附加一个属性
__jsb_ns_SomeClass_proto->setProperty("yyy", se::Value("helloyyy"));
// 注册静态成员变量和静态成员函数
se::Value ctorVal;
if (ns->getProperty("SomeClass", &ctorVal) && ctorVal.isObject())
{
ctorVal.toObject()->setProperty("static_val", se::Value(200));
ctorVal.toObject()->defineFunction("static_func", _SE(js_SomeClass_static_func));
}
// 清空异常
se::ScriptEngine::getInstance()->clearException();
return true;
}




赞赞赞