{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/cocos-jsb/",
  "atlas": "https://www.pystone.net/?node=cocos-jsb#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/cocos-jsb.md",
  "context": "https://www.pystone.net/notes/cocos-jsb.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:cocos-jsb",
  "slug": "cocos-jsb",
  "title": "Cocos-JSB",
  "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": "一些问题： // 在全局注册集中调用 include \"bindings/ManualBindings.h\" // 举例，放到你的集中注册处 void register all modules() { auto se = se::ScriptEngine::getInstance(); se addRegisterCallback([](se::Object global){ se::Value nativeNS; if (!gl…",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "b10779ff1a8f0d54ce6dbfb5608454cf7199a6cb09e1f515f62404305001ef54",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "Cocos-JSB",
      "anchor": "cocos-jsb",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#cocos-jsb"
    },
    {
      "depth": 2,
      "text": "Cocos Creator 3.8 的引擎架构与 JSB 基础设施",
      "anchor": "cocos-creator-38-的引擎架构与-jsb-基础设施",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#cocos-creator-38-%E7%9A%84%E5%BC%95%E6%93%8E%E6%9E%B6%E6%9E%84%E4%B8%8E-jsb-%E5%9F%BA%E7%A1%80%E8%AE%BE%E6%96%BD"
    },
    {
      "depth": 2,
      "text": "双内核 + TS 框架层",
      "anchor": "双内核-ts-框架层",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#%E5%8F%8C%E5%86%85%E6%A0%B8-ts-%E6%A1%86%E6%9E%B6%E5%B1%82"
    },
    {
      "depth": 2,
      "text": "ScriptEngine 抽象层（JSB 2.0 的地基）",
      "anchor": "scriptengine-抽象层jsb-20-的地基",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#scriptengine-%E6%8A%BD%E8%B1%A1%E5%B1%82jsb-20-%E7%9A%84%E5%9C%B0%E5%9F%BA"
    },
    {
      "depth": 2,
      "text": "自动绑定",
      "anchor": "自动绑定",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#%E8%87%AA%E5%8A%A8%E7%BB%91%E5%AE%9A"
    },
    {
      "depth": 2,
      "text": "准备环境",
      "anchor": "准备环境",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#%E5%87%86%E5%A4%87%E7%8E%AF%E5%A2%83"
    },
    {
      "depth": 2,
      "text": "Native目录生成",
      "anchor": "native目录生成",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#native%E7%9B%AE%E5%BD%95%E7%94%9F%E6%88%90"
    },
    {
      "depth": 2,
      "text": "写 C++ 头/源（你的原生能力）",
      "anchor": "写-c-头源你的原生能力",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#%E5%86%99-c-%E5%A4%B4%E6%BA%90%E4%BD%A0%E7%9A%84%E5%8E%9F%E7%94%9F%E8%83%BD%E5%8A%9B"
    },
    {
      "depth": 2,
      "text": "编写自动绑定的 .ini 配置",
      "anchor": "编写自动绑定的-ini-配置",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#%E7%BC%96%E5%86%99%E8%87%AA%E5%8A%A8%E7%BB%91%E5%AE%9A%E7%9A%84-ini-%E9%85%8D%E7%BD%AE"
    },
    {
      "depth": 2,
      "text": "运行绑定生成脚本",
      "anchor": "运行绑定生成脚本",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#%E8%BF%90%E8%A1%8C%E7%BB%91%E5%AE%9A%E7%94%9F%E6%88%90%E8%84%9A%E6%9C%AC"
    },
    {
      "depth": 2,
      "text": "在原生工程中注册模块",
      "anchor": "在原生工程中注册模块",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#%E5%9C%A8%E5%8E%9F%E7%94%9F%E5%B7%A5%E7%A8%8B%E4%B8%AD%E6%B3%A8%E5%86%8C%E6%A8%A1%E5%9D%97"
    },
    {
      "depth": 2,
      "text": "构建 / 编译 / 运行",
      "anchor": "构建-编译-运行",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#%E6%9E%84%E5%BB%BA-%E7%BC%96%E8%AF%91-%E8%BF%90%E8%A1%8C"
    },
    {
      "depth": 2,
      "text": "TS 侧调用",
      "anchor": "ts-侧调用",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#ts-%E4%BE%A7%E8%B0%83%E7%94%A8"
    },
    {
      "depth": 2,
      "text": "手动绑定（Manual Binding）",
      "anchor": "手动绑定manual-binding",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#%E6%89%8B%E5%8A%A8%E7%BB%91%E5%AE%9Amanual-binding"
    },
    {
      "depth": 2,
      "text": "1) 目录结构（相对项目根）",
      "anchor": "1-目录结构相对项目根",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#1-%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84%E7%9B%B8%E5%AF%B9%E9%A1%B9%E7%9B%AE%E6%A0%B9"
    },
    {
      "depth": 2,
      "text": "2) 原生功能（C++）",
      "anchor": "2-原生功能c",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#2-%E5%8E%9F%E7%94%9F%E5%8A%9F%E8%83%BDc"
    },
    {
      "depth": 2,
      "text": "native/engine/common/Classes/MyMath.h",
      "anchor": "nativeenginecommonclassesmymathh",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#nativeenginecommonclassesmymathh"
    },
    {
      "depth": 2,
      "text": "native/engine/common/Classes/MyMath.cpp",
      "anchor": "nativeenginecommonclassesmymathcpp",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#nativeenginecommonclassesmymathcpp"
    },
    {
      "depth": 2,
      "text": "3) 绑定层（se::Class + SE\\BIND\\\\ 宏）",
      "anchor": "3-绑定层seclass-sebind-宏",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#3-%E7%BB%91%E5%AE%9A%E5%B1%82seclass-sebind-%E5%AE%8F"
    },
    {
      "depth": 2,
      "text": "native/engine/common/Classes/MyMathBinding.cpp",
      "anchor": "nativeenginecommonclassesmymathbindingcpp",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#nativeenginecommonclassesmymathbindingcpp"
    },
    {
      "depth": 2,
      "text": "native/engine/common/Classes/MyMathBinding.h",
      "anchor": "nativeenginecommonclassesmymathbindingh",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#nativeenginecommonclassesmymathbindingh"
    },
    {
      "depth": 2,
      "text": "4) 集中注册处（统一挂到 global.native.\\）",
      "anchor": "4-集中注册处统一挂到-globalnative",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#4-%E9%9B%86%E4%B8%AD%E6%B3%A8%E5%86%8C%E5%A4%84%E7%BB%9F%E4%B8%80%E6%8C%82%E5%88%B0-globalnative"
    },
    {
      "depth": 2,
      "text": "native/engine/common/Classes/Bindings.h",
      "anchor": "nativeenginecommonclassesbindingsh",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#nativeenginecommonclassesbindingsh"
    },
    {
      "depth": 2,
      "text": "native/engine/common/Classes/Bindings.cpp",
      "anchor": "nativeenginecommonclassesbindingscpp",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#nativeenginecommonclassesbindingscpp"
    },
    {
      "depth": 2,
      "text": "5) 在引擎启动时注册（调用时机）",
      "anchor": "5-在引擎启动时注册调用时机",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#5-%E5%9C%A8%E5%BC%95%E6%93%8E%E5%90%AF%E5%8A%A8%E6%97%B6%E6%B3%A8%E5%86%8C%E8%B0%83%E7%94%A8%E6%97%B6%E6%9C%BA"
    },
    {
      "depth": 2,
      "text": "6) CMake 配置（把源码编进原生工程）",
      "anchor": "6-cmake-配置把源码编进原生工程",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#6-cmake-%E9%85%8D%E7%BD%AE%E6%8A%8A%E6%BA%90%E7%A0%81%E7%BC%96%E8%BF%9B%E5%8E%9F%E7%94%9F%E5%B7%A5%E7%A8%8B"
    },
    {
      "depth": 2,
      "text": "7) 脚本侧使用（TS/JS）",
      "anchor": "7-脚本侧使用tsjs",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#7-%E8%84%9A%E6%9C%AC%E4%BE%A7%E4%BD%BF%E7%94%A8tsjs"
    },
    {
      "depth": 2,
      "text": "assets/scripts/NativeDemo.ts",
      "anchor": "assetsscriptsnativedemots",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#assetsscriptsnativedemots"
    },
    {
      "depth": 2,
      "text": "8) （可选）给 TS 补类型声明",
      "anchor": "8-可选给-ts-补类型声明",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#8-%E5%8F%AF%E9%80%89%E7%BB%99-ts-%E8%A1%A5%E7%B1%BB%E5%9E%8B%E5%A3%B0%E6%98%8E"
    },
    {
      "depth": 2,
      "text": "assets/@types/native-demo.d.ts",
      "anchor": "assetstypesnative-demodts",
      "citation": "https://www.pystone.net/notes/cocos-jsb/#assetstypesnative-demodts"
    }
  ],
  "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中的“Cocos-JSB”导航项",
      "citation": "https://www.pystone.net/notes/game-graphics-and-runtime/#cocos"
    }
  ],
  "contentMarkdown": "一些问题：\n// 在全局注册集中调用\n#include \"bindings/ManualBindings.h\" // 举例，放到你的集中注册处\nvoid register_all_modules() {\n    auto* se = se::ScriptEngine::getInstance();\n    se->addRegisterCallback([](se::Object* global){\n        se::Value nativeNS;\n        if (!global->getProperty(\"native\", &nativeNS) || !nativeNS.isObject()) {\n            nativeNS.setObject(se::Object::createPlainObject());\n            global->setProperty(\"native\", nativeNS);\n        }\n        register_all_mymath(nativeNS.toObject());\n    });\n}\n\n这个集中注册处，应该写在哪里，在什么时机会被调用，把调用该函数的代码写在哪里？\n\n请帮我解释 抽象层、宏与回调签名\n\nSE_BIND_FUNC 的本质和作用是什么\n\nJSB的底层原理是什么（具体到编译器、运行时的原理）\n\nJSB暴露类型个JS的方法是什么\n\n# Cocos-JSB\n- **JSB 是什么**：把 C++/Objective-C/Java 的原生能力“绑定”为 JS/TS 可调用接口的机制。它让你的脚本像调用普通 TS API 一样调用底层原生实现。\n\n- **什么时候用 JSB**：\n\n    - 频繁、低延迟调用的功能（如音视频、文件/网络 I/O、数学/加解密、AI SDK、复杂物理等）；\n\n    - 需要直接复用原生库（C/C++/ObjC/Java）的场景；\n\n    - 避免反射 `callStaticMethod` 的高开销与易错（字符串拼装、JNI 本地引用溢出）等问题。官方也明确建议**大量频繁调用尽量走 JSB**，性能和稳定性更好。[docs.cocos.com](https://docs.cocos.com/creator/3.8/manual/zh/advanced-topics/jsb-auto-binding.html?utm_source=chatgpt.com)\n\n## Cocos Creator 3.8 的引擎架构与 JSB 基础设施\n## 双内核 + TS 框架层\n\n- Creator 3.8 有两套内核：**C++ 内核（原生平台）** 与 **TypeScript 内核（Web/小游戏）**；上层是统一的 **TS 引擎框架层**，尽量抹平平台差异。\n\n## ScriptEngine 抽象层（JSB 2.0 的地基）\n\n- 引擎将具体 JS 引擎（V8 / JavaScriptCore / SpiderMonkey / Chakra 等）的差异封装在 **`se::ScriptEngine`** 抽象层里；开发者写绑定时用统一的 `se::` 类型与宏，不直接面对 V8/JSC 的差异。核心类型如 `se::ScriptEngine`、`se::Class`、`se::Value`、`se::Object`、以及 `SE_BIND_FUNC` 等宏。\n- 这层设计**可独立于引擎使用**，位于 `cocos/bindings/jswrapper`。\n\n\n## 自动绑定\n\n\n## 准备环境\n\n1. 获取匹配 3.8 的 **cocos-engine 源码**（或使用内置引擎；定制请在“引擎管理器”里切换到自定义路径）。\n2. 安装引擎 `native/external` 依赖（`gulp init` 或从仓库下载指定 tag 的 zip）。\n3. 需要 Node.js、Python 及生成工具链（文档会写明具体依赖）。\n\n\n## Native目录生成\n确保 native 目录存在\n如果项目目录下没有 native 目录需要在编辑器中 Build(生成)一次来创建 native 目录。\n\n复制 assets 和 native 目录到项目目录中\n\n增加 C++编译项\n在 `<项目名>\\native\\engine\\common\\CMakeLists.txt` 中为 `CC_COMMON_SOURCES` 追加 编译项，以默认项目为例：\n\n```cpp\nlist(APPEND CC_COMMON_SOURCES\n ${CMAKE_CURRENT_LIST_DIR}/Classes/Game.h\n ${CMAKE_CURRENT_LIST_DIR}/Classes/Game.cpp\n ${CMAKE_CURRENT_LIST_DIR}/Classes/xxx.h\n ${CMAKE_CURRENT_LIST_DIR}/Classes/xxx.cpp\n)\n```\n\n## 写 C++ 头/源（你的原生能力）\n\n```cpp\n// native/my_math/MyMath.h\n#pragma once\nclass MyMath {\npublic:\n    static int add(int a, int b);\n};\n\n// native/my_math/MyMath.cpp\n#include \"MyMath.h\"\nint MyMath::add(int a, int b) { return a + b; }\n```\n\n## 编写自动绑定的 `.ini` 配置\n\n以 Creator 的自动绑定流程为例（核心思想：指明要导出的头文件、命名空间、需要生成哪些函数/类）。在你的引擎/项目绑定配置目录中新增类似：\n\n```ini\n## mymath.ini（示例）\n[cocos-bindings]\nclasses = MyMath\nheaders = native/my_math/MyMath.h\n## 也可以细化只导出哪些方法\n```\n\n## 运行绑定生成脚本\n\n* 在引擎的 tojs 工具下执行生成命令（不同版本可能是 `tools/tojs/genbindings.py` 或 gulp 任务）：\n  `python tools/tojs/genbindings.py -c mymath.ini`\n* 生成的 **绑定 C++ 源**（通常是 `auto/jsb_mymath_auto.cpp` 一类）会出现在绑定输出目录。\n\n## 在原生工程中**注册模块**\n\n在你的模块初始化处（例如自定义 `register_all_mymath()`），调用生成代码里的注册函数，把类挂到 JS（建议挂到 `native` 下的自命名空间而非全局 `jsb`）：\n\n```cpp\nbool register_all_mymath(se::Object* ns) {\n    // 由自动生成代码提供：创建 JS 类、绑定静态方法 add\n    extern bool js_register_cocos_mymath(se::Object* ns);\n    return js_register_cocos_mymath(ns);\n}\n\n// 在全局注册集中调用\n#include \"bindings/ManualBindings.h\" // 举例，放到你的集中注册处\nvoid register_all_modules() {\n    auto* se = se::ScriptEngine::getInstance();\n    se->addRegisterCallback([](se::Object* global){\n        se::Value nativeNS;\n        if (!global->getProperty(\"native\", &nativeNS) || !nativeNS.isObject()) {\n            nativeNS.setObject(se::Object::createPlainObject());\n            global->setProperty(\"native\", nativeNS);\n        }\n        register_all_mymath(nativeNS.toObject());\n    });\n}\n```\n\n\n## 构建 / 编译 / 运行\n\n* **构建原生工程**：项目 → 构建发布 → 选择平台（Android/iOS/macOS/Windows）→ 构建 → 生成（Make）→ 运行；也可直接用对应 IDE 编译。\n* 如果你采用**自定义引擎**，需在“引擎管理器”切换路径；修改 C++ 后可在 IDE 里直接编译。\n\n## TS 侧调用\n\n```ts\nimport { native } from 'cc';\nconst sum = (native as any).mymath.add(3, 5); // 期望 8\n```\n\n\n## 手动绑定（Manual Binding）\n\n## 1) 目录结构（相对项目根）\n\n```xml\n<YourProject>/\n├─ assets/\n│  ├─ scripts/\n│  │   └─ NativeDemo.ts\n│  └─ @types/             # 可选：给 TS 加类型\n│      └─ native-demo.d.ts\n└─ native/\n   └─ engine/\n      ├─ common/\n      │  ├─ Classes/\n      │  │   ├─ Bindings.h\n      │  │   ├─ Bindings.cpp\n      │  │   ├─ MyMath.h\n      │  │   ├─ MyMath.cpp\n      │  │   ├─ MyMathBinding.cpp\n      │  │   └─ NetBinding.cpp\n      │  └─ CMakeLists.txt         # 需追加几行（见下）\n      └─ common/Classes/Game.cpp   # 已存在；需追加几行（见下）\n```\n\n---\n\n## 2) 原生功能（C++）\n\n## `native/engine/common/Classes/MyMath.h`\n\n```cpp\n#pragma once\n#include <cmath>\n\nclass MyMath {\npublic:\n    static int add(int a, int b) { return a + b; }\n    static double hypot(double x, double y) { return std::hypot(x, y); }\n};\n```\n\n## `native/engine/common/Classes/MyMath.cpp`\n\n```cpp\n#include \"MyMath.h\"\n// 这里目前没特别逻辑，保留源文件便于扩展与编译器增量构建\n```\n\n---\n\n## 3) 绑定层（se::Class + SE\\_BIND\\_\\* 宏）\n\n> 头文件路径使用引擎提供的 JS 包装抽象层：`bindings/jswrapper/SeApi.h`\n\n## `native/engine/common/Classes/MyMathBinding.cpp`\n\n```cpp\n#include \"bindings/jswrapper/SeApi.h\"\n#include \"MyMathBinding.h\"\n#include \"MyMath.h\"\n\nusing namespace se;\n\n// --- 静态方法：add(a,b): number ---\nstatic bool js_mymath_add(State& s) {\n    const auto& args = s.args();\n    int a = (args.size() > 0 && args[0].isNumber()) ? args[0].toInt32() : 0;\n    int b = (args.size() > 1 && args[1].isNumber()) ? args[1].toInt32() : 0;\n    s.rval().setInt32(MyMath::add(a, b));\n    return true;\n}\nSE_BIND_FUNC(js_mymath_add)\n\n// --- 静态方法：hypot(x,y): number ---\nstatic bool js_mymath_hypot(State& s) {\n    const auto& args = s.args();\n    double x = (args.size() > 0 && args[0].isNumber()) ? args[0].toNumber() : 0.0;\n    double y = (args.size() > 1 && args[1].isNumber()) ? args[1].toNumber() : 0.0;\n    s.rval().setNumber(MyMath::hypot(x, y));\n    return true;\n}\nSE_BIND_FUNC(js_mymath_hypot)\n\n// 将 MyMath 以“纯静态类”形式挂到 global.native.mymath\nbool register_all_mymath(se::Object* ns) {\n    // 定义一个没有 ctor 的类：native.mymath\n    auto* cls = se::Class::create(\"mymath\", ns, nullptr, nullptr);\n    // 静态方法\n    cls->defineStaticFunction(\"add\",   _SE(js_mymath_add));\n    cls->defineStaticFunction(\"hypot\", _SE(js_mymath_hypot));\n    // 安装类：把 “mymath” 放到传入命名空间 ns（即 native）下\n    cls->install();\n    se::ScriptEngine::getInstance()->clearException();\n    return true;\n}\n```\n\n## `native/engine/common/Classes/MyMathBinding.h`\n\n```cpp\n#pragma once\n#include \"bindings/jswrapper/SeApi.h\"\n\n// 把 MyMath 静态方法暴露到 JS 的注册函数\n// ns 参数通常是 global.native 对应的 se::Object*\nbool register_all_mymath(se::Object* ns);\n\n```\n\n---\n\n## 4) 集中注册处（统一挂到 global.native.\\*）\n\n## `native/engine/common/Classes/Bindings.h`\n\n```cpp\n#pragma once\n#include \"bindings/jswrapper/SeApi.h\"\n#include \"MyMathBinding.h\"  // 引入 MyMath 的注册声明\n\n// 各模块的注册函数\nbool register_all_mymath(se::Object* ns);\nbool register_all_net(se::Object* ns);\n\n// 总注册：负责准备 global.native 命名空间，并调用各模块注册\nbool register_all_modules(se::Object* global);\n```\n\n## `native/engine/common/Classes/Bindings.cpp`\n\n```cpp\n#include \"Bindings.h\"\n\nbool register_all_modules(se::Object* global) {\n    // 准备 global.native 命名空间\n    se::Value nativeNS;\n    if (!global->getProperty(\"native\", &nativeNS) || !nativeNS.isObject()) {\n        nativeNS.setObject(se::Object::createPlainObject());\n        global->setProperty(\"native\", nativeNS);\n    }\n    auto* ns = nativeNS.toObject();\n\n    bool ok = true;\n    ok &= register_all_mymath(ns);\n    ok &= register_all_net(ns);\n    return ok;\n}\n```\n\n---\n\n## 5) 在引擎启动时注册（调用时机）\n\n> **放在 `Game.cpp::init()`**：引擎创建 JS 运行时后，会依次执行你登记的 “RegisterCallback” 来把类型/函数挂到 JS 全局。\n\n打开现有的 `native/engine/common/Classes/Game.cpp`，找到 `Game::init()`，按下方方式**补几行**（不要误删你工程里的其他逻辑）：\n\n```cpp\n#include \"Game.h\"\n#include \"Bindings.h\" // <== 新增\n\nint Game::init() {\n    // 你项目已有的初始化逻辑...\n    auto* se = se::ScriptEngine::getInstance();\n\n    // 【关键】把“总注册”加到回调队列\n    se->addRegisterCallback([](se::Object* global){\n        register_all_modules(global); // 我们的总注册函数\n    });\n\n    // 原有：启动/初始化 ScriptEngine、加载脚本等\n    BaseGame::init();\n    return 0;\n}\n```\n\n> 注意：不同模板里类名可能叫 `AppDelegate`/`Game`/`BaseGame`，但**核心点**是不变的——把你的注册函数通过 `addRegisterCallback` 丢给 `ScriptEngine`，由引擎在初始化 JS 环境时调用。\n\n---\n\n## 6) CMake 配置（把源码编进原生工程）\n\n打开 `native/engine/common/CMakeLists.txt`（文件已存在）。给目标里**追加源码文件**（变量名通常为 `${APP_NAME}`；若模板使用 `${PROJECT_NAME}`，请替换即可）：\n\n\n```cmake\nlist(APPEND CC_COMMON_SOURCES\n    ${CMAKE_CURRENT_LIST_DIR}/Classes/Bindings.cpp\n    ${CMAKE_CURRENT_LIST_DIR}/Classes/Bindings.h\n    ${CMAKE_CURRENT_LIST_DIR}/Classes/MyMath.h\n    ${CMAKE_CURRENT_LIST_DIR}/Classes/MyMath.cpp\n    ${CMAKE_CURRENT_LIST_DIR}/Classes/MyMathBinding.cpp\n    ${CMAKE_CURRENT_LIST_DIR}/Classes/MyMathBinding.h\n)\n\n```\n\n```cmake\n## 在现有内容的基础上，追加这几行：\ntarget_sources(${APP_NAME}\n    PRIVATE\n        common/Classes/Bindings.cpp\n        common/Classes/MyMath.cpp\n        common/Classes/MyMathBinding.cpp\n        common/Classes/NetBinding.cpp\n)\n\n## 如需（一般不用），也可加头文件目录：\n## target_include_directories(${APP_NAME} PRIVATE common/Classes)\n```\n\n> 保存后回到 Creator：**构建 -> 生成（Make）**；或用对应 IDE（Xcode/Android Studio/VS）编译运行。\n\n---\n\n## 7) 脚本侧使用（TS/JS）\n\n## `assets/scripts/NativeDemo.ts`\n\n```ts\n// 运行于原生平台（Android/iOS/macOS/Windows）\nconst g: any = globalThis as any;\n\nexport function runDemo() {\n    // 1) 调用 native.mymath\n    const sum = g.native.mymath.add(3, 5);\n    const h   = g.native.mymath.hypot(3, 4);\n    console.log('native.mymath.add(3,5)=', sum);   // 8\n    console.log('native.mymath.hypot(3,4)=', h);   // 5\n\n    // 2) 调用 native.net\n    console.log('native.net.ping() =', g.native.net.ping()); // \"pong\"\n}\n```\n\n（可选）在某个组件 `onLoad()` 或按钮回调里调用 `runDemo()` 即可。\n\n---\n\n## 8) （可选）给 TS 补类型声明\n\n## `assets/@types/native-demo.d.ts`\n\n```ts\ndeclare global {\n    // 挂到 globalThis 下的 native 命名空间\n    var native: {\n        mymath: {\n            add(a: number, b: number): number;\n            hypot(x: number, y: number): number;\n        };\n        net: {\n            ping(): string;\n        };\n    };\n}\nexport {};\n```\n"
}
