---
title: "Cocos2dx binding"
author: "Perrin Yong"
author_profile: https://www.pystone.net/profile/
published_by: "Perrin Yong"
canonical: https://www.pystone.net/notes/cocos2dx-binding/
type: note
content_role: unspecified
visibility: public
id_stability: rename-stable
source_path: "10-计算机、信息技术与工程/05-游戏图形与运行时/Cocos/Cocos2dx binding.md"
content_hash: 75a3e2255f3cec8d1a98cb7a59da2623e96d8252c4dc8fadeca7056d06dd10f2
knowledge_version: 224c990773de.5fa8af6e39fa
site_commit: 224c990773de166d23a886306577dd90379529ce
notes_commit: 5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a
---
# Cocos2dx binding

﻿# Cocos2dx binding


## JSB

```cpp
// MyApiJSB.cpp
#include "scripting/js-bindings/manual/ScriptingCore.h"
#include "MyApi.h"

static bool js_myapi_echo(JSContext* cx, uint32_t argc, jsval* vp) {
    if (argc == 1) {
        JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
        std::string s;
        if (args.get(0).isString()) {
            JS::RootedString rs(cx, args.get(0).toString());
            s = JS_EncodeStringToUTF8(cx, rs);
        } else return false;

        auto out = MyApi::echo(s);
        JS::RootedString jsOut(cx, JS_NewStringCopyZ(cx, out.c_str()));
        args.rval().set(STRING_TO_JSVAL(jsOut));
        return true;
    }
    return false;
}

static void bind_myapi(JSContext* cx, JS::HandleObject global) {
    static JSFunctionSpec specs[] = {
        JS_FN("echo", js_myapi_echo, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FS_END
    };
    JS::RootedObject ns(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
    JS::RootedValue  v(cx, OBJECT_TO_JSVAL(ns));
    JS_SetProperty(cx, global, "myapi", v);
    JS_DefineFunctions(cx, ns, specs);
}

// somewhere in startup (e.g., AppDelegate)
auto se = ScriptingCore::getInstance();
if (auto cx = se->getGlobalContext()) {
    JS::RootedObject g(cx, se->getGlobalObject());
    bind_myapi(cx, g);
} else {
    se->addRegisterCallback(bind_myapi);
}

```


JS 端即可：
```js
myapi.echo("hello"); // -> "hello"
```


## Lua

### 1) 最小可用 C++ 代码（`MyLuaBindings.cpp`）
```cpp
// MyLuaBindings.cpp —— 加入到你的原生工程参与编译
#include "cocos2d.h"
#include "scripting/lua-bindings/manual/CCLuaEngine.h"
#include "tolua++.h"   // 若报未定义的 tolua_*，补这个头

using namespace cocos2d;

#define MY_LUA_NS "myapi"   // Lua 侧的命名空间：myapi.xxx

// —— 示例的原生状态（仅演示）——
namespace MyNative {
    static int value = 0;
    static void        setValue(int v) { value = v; }
    static int         getValue()      { return value; }
    static std::string greet(const char* name) {
        return std::string("Hello, ") + (name ? name : "");
    }
}

// 1) 绑定函数：入参校验 + 业务调用 + 压回返回值数量

// myapi.setValue(number)
static int lua_myapi_setValue(lua_State* L) {
    int argc = lua_gettop(L);
    if (argc != 1 || !lua_isnumber(L, 1)) {
        CCLOGERROR("myapi.setValue(number) expects 1 number");
        return 0;
    }
    MyNative::setValue((int)lua_tointeger(L, 1));
    return 0; // 返回 0 个值
}

// local v = myapi.getValue()
static int lua_myapi_getValue(lua_State* L) {
    lua_pushinteger(L, MyNative::getValue());
    return 1; // 返回 1 个值
}

// local s = myapi.greet("Cocos")
static int lua_myapi_greet(lua_State* L) {
    const char* name = luaL_checkstring(L, 1);        // 不符会抛 Lua 错误
    std::string s = MyNative::greet(name);
    lua_pushlstring(L, s.c_str(), s.size());
    return 1;
}

// 2) 把函数注册进 Lua 命名空间：myapi
static void bindMyLuaFunctions(lua_State* L) {
    if (!L) { CCLOGERROR("bindMyLuaFunctions: null lua_State"); return; }

    lua_getglobal(L, "_G");                 // stack: ... _G
    if (lua_istable(L, -1)) {
        tolua_open(L);
        tolua_module(L, MY_LUA_NS, 0);
        tolua_beginmodule(L, MY_LUA_NS);

        tolua_function(L, "setValue", lua_myapi_setValue);
        tolua_function(L, "getValue", lua_myapi_getValue);
        tolua_function(L, "greet",    lua_myapi_greet);

        tolua_endmodule(L);
    }
    lua_pop(L, 1);                          // pop _G
}

// 3) 对外导出一个“注册入口”，在启动时调用一次
void registerMyLuaBindings() {
    auto engine = LuaEngine::getInstance();
    if (!engine) { CCLOGERROR("LuaEngine not found"); return; }
    bindMyLuaFunctions(engine->getLuaStack()->getLuaState());
}

```


### 2) 在启动流程里调用一次
```cpp
// AppDelegate.cpp
bool AppDelegate::applicationDidFinishLaunching() {
    // ... 你的初始化 ...
    registerMyLuaBindings();  // ★ 注册 Lua 绑定
    // ... 继续加载 Lua 脚本等 ...
    return true;
}

```

### 3) Lua 侧用法示例
```lua
myapi.setValue(42)
print("value =", myapi.getValue())     -- 42
print(myapi.greet("Cocos"))            -- "Hello, Cocos"
```
