{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/cocos2dx-binding/",
  "atlas": "https://www.pystone.net/?node=cocos2dx-binding#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/cocos2dx-binding.md",
  "context": "https://www.pystone.net/notes/cocos2dx-binding.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:cocos2dx-binding",
  "slug": "cocos2dx-binding",
  "title": "Cocos2dx binding",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "Cocos2dx binding",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "75a3e2255f3cec8d1a98cb7a59da2623e96d8252c4dc8fadeca7056d06dd10f2",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "Cocos2dx binding",
      "anchor": "cocos2dx-binding",
      "citation": "https://www.pystone.net/notes/cocos2dx-binding/#cocos2dx-binding"
    },
    {
      "depth": 2,
      "text": "JSB",
      "anchor": "jsb",
      "citation": "https://www.pystone.net/notes/cocos2dx-binding/#jsb"
    },
    {
      "depth": 2,
      "text": "Lua",
      "anchor": "lua",
      "citation": "https://www.pystone.net/notes/cocos2dx-binding/#lua"
    },
    {
      "depth": 3,
      "text": "1) 最小可用 C++ 代码（MyLuaBindings.cpp）",
      "anchor": "1-最小可用-c-代码myluabindingscpp",
      "citation": "https://www.pystone.net/notes/cocos2dx-binding/#1-%E6%9C%80%E5%B0%8F%E5%8F%AF%E7%94%A8-c-%E4%BB%A3%E7%A0%81myluabindingscpp"
    },
    {
      "depth": 3,
      "text": "2) 在启动流程里调用一次",
      "anchor": "2-在启动流程里调用一次",
      "citation": "https://www.pystone.net/notes/cocos2dx-binding/#2-%E5%9C%A8%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B%E9%87%8C%E8%B0%83%E7%94%A8%E4%B8%80%E6%AC%A1"
    },
    {
      "depth": 3,
      "text": "3) Lua 侧用法示例",
      "anchor": "3-lua-侧用法示例",
      "citation": "https://www.pystone.net/notes/cocos2dx-binding/#3-lua-%E4%BE%A7%E7%94%A8%E6%B3%95%E7%A4%BA%E4%BE%8B"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:game-graphics-and-runtime",
      "title": "游戏图形与运行时",
      "url": "https://www.pystone.net/notes/game-graphics-and-runtime/",
      "atlas": "https://www.pystone.net/?node=game-graphics-and-runtime#knowledge-atlas",
      "label": "游戏图形与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": "Cocos中的“Cocos2dx binding”导航项",
      "citation": "https://www.pystone.net/notes/game-graphics-and-runtime/#cocos"
    }
  ],
  "contentMarkdown": "# Cocos2dx binding\n\n﻿# Cocos2dx binding\n\n\n## JSB\n\n```cpp\n// MyApiJSB.cpp\n#include \"scripting/js-bindings/manual/ScriptingCore.h\"\n#include \"MyApi.h\"\n\nstatic bool js_myapi_echo(JSContext* cx, uint32_t argc, jsval* vp) {\n    if (argc == 1) {\n        JS::CallArgs args = JS::CallArgsFromVp(argc, vp);\n        std::string s;\n        if (args.get(0).isString()) {\n            JS::RootedString rs(cx, args.get(0).toString());\n            s = JS_EncodeStringToUTF8(cx, rs);\n        } else return false;\n\n        auto out = MyApi::echo(s);\n        JS::RootedString jsOut(cx, JS_NewStringCopyZ(cx, out.c_str()));\n        args.rval().set(STRING_TO_JSVAL(jsOut));\n        return true;\n    }\n    return false;\n}\n\nstatic void bind_myapi(JSContext* cx, JS::HandleObject global) {\n    static JSFunctionSpec specs[] = {\n        JS_FN(\"echo\", js_myapi_echo, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),\n        JS_FS_END\n    };\n    JS::RootedObject ns(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));\n    JS::RootedValue  v(cx, OBJECT_TO_JSVAL(ns));\n    JS_SetProperty(cx, global, \"myapi\", v);\n    JS_DefineFunctions(cx, ns, specs);\n}\n\n// somewhere in startup (e.g., AppDelegate)\nauto se = ScriptingCore::getInstance();\nif (auto cx = se->getGlobalContext()) {\n    JS::RootedObject g(cx, se->getGlobalObject());\n    bind_myapi(cx, g);\n} else {\n    se->addRegisterCallback(bind_myapi);\n}\n\n```\n\n\nJS 端即可：\n```js\nmyapi.echo(\"hello\"); // -> \"hello\"\n```\n\n\n## Lua\n\n### 1) 最小可用 C++ 代码（`MyLuaBindings.cpp`）\n```cpp\n// MyLuaBindings.cpp —— 加入到你的原生工程参与编译\n#include \"cocos2d.h\"\n#include \"scripting/lua-bindings/manual/CCLuaEngine.h\"\n#include \"tolua++.h\"   // 若报未定义的 tolua_*，补这个头\n\nusing namespace cocos2d;\n\n#define MY_LUA_NS \"myapi\"   // Lua 侧的命名空间：myapi.xxx\n\n// —— 示例的原生状态（仅演示）——\nnamespace MyNative {\n    static int value = 0;\n    static void        setValue(int v) { value = v; }\n    static int         getValue()      { return value; }\n    static std::string greet(const char* name) {\n        return std::string(\"Hello, \") + (name ? name : \"\");\n    }\n}\n\n// 1) 绑定函数：入参校验 + 业务调用 + 压回返回值数量\n\n// myapi.setValue(number)\nstatic int lua_myapi_setValue(lua_State* L) {\n    int argc = lua_gettop(L);\n    if (argc != 1 || !lua_isnumber(L, 1)) {\n        CCLOGERROR(\"myapi.setValue(number) expects 1 number\");\n        return 0;\n    }\n    MyNative::setValue((int)lua_tointeger(L, 1));\n    return 0; // 返回 0 个值\n}\n\n// local v = myapi.getValue()\nstatic int lua_myapi_getValue(lua_State* L) {\n    lua_pushinteger(L, MyNative::getValue());\n    return 1; // 返回 1 个值\n}\n\n// local s = myapi.greet(\"Cocos\")\nstatic int lua_myapi_greet(lua_State* L) {\n    const char* name = luaL_checkstring(L, 1);        // 不符会抛 Lua 错误\n    std::string s = MyNative::greet(name);\n    lua_pushlstring(L, s.c_str(), s.size());\n    return 1;\n}\n\n// 2) 把函数注册进 Lua 命名空间：myapi\nstatic void bindMyLuaFunctions(lua_State* L) {\n    if (!L) { CCLOGERROR(\"bindMyLuaFunctions: null lua_State\"); return; }\n\n    lua_getglobal(L, \"_G\");                 // stack: ... _G\n    if (lua_istable(L, -1)) {\n        tolua_open(L);\n        tolua_module(L, MY_LUA_NS, 0);\n        tolua_beginmodule(L, MY_LUA_NS);\n\n        tolua_function(L, \"setValue\", lua_myapi_setValue);\n        tolua_function(L, \"getValue\", lua_myapi_getValue);\n        tolua_function(L, \"greet\",    lua_myapi_greet);\n\n        tolua_endmodule(L);\n    }\n    lua_pop(L, 1);                          // pop _G\n}\n\n// 3) 对外导出一个“注册入口”，在启动时调用一次\nvoid registerMyLuaBindings() {\n    auto engine = LuaEngine::getInstance();\n    if (!engine) { CCLOGERROR(\"LuaEngine not found\"); return; }\n    bindMyLuaFunctions(engine->getLuaStack()->getLuaState());\n}\n\n```\n\n\n### 2) 在启动流程里调用一次\n```cpp\n// AppDelegate.cpp\nbool AppDelegate::applicationDidFinishLaunching() {\n    // ... 你的初始化 ...\n    registerMyLuaBindings();  // ★ 注册 Lua 绑定\n    // ... 继续加载 Lua 脚本等 ...\n    return true;\n}\n\n```\n\n### 3) Lua 侧用法示例\n```lua\nmyapi.setValue(42)\nprint(\"value =\", myapi.getValue())     -- 42\nprint(myapi.greet(\"Cocos\"))            -- \"Hello, Cocos\"\n```\n"
}
