# QuickJS C/JS 交互示例 本项目演示了 C 和 JavaScript 之间的各种交互方式。 ## 编译 ```powershell cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release ``` ## 运行示例 ### 简单示例 (simple_demo) ```powershell .\build\bin\Release\simple_demo.exe ``` 简单示例包含: - 基本的 JavaScript 表达式求值 - 字符串操作 - JavaScript 函数调用 - 从 JavaScript 调用 C 函数 ### 完整示例 (demo) ```powershell .\build\bin\Release\demo.exe ``` 完整示例包含: 1. **基本 JavaScript 执行** - 执行简单的 JS 表达式和函数 2. **从 C 调用 JavaScript 函数** - 调用 JS 函数并处理返回值 3. **从 JavaScript 调用 C 函数** - 注册 C 函数供 JS 调用 4. **数据类型转换** - 在 C 和 JS 之间转换各种数据类型 5. **对象操作** - 创建和操作 JavaScript 对象 6. **数组操作** - 创建和操作 JavaScript 数组 7. **异常处理** - 处理 JS 和 C 中的异常 8. **内存管理** - JSValue 的引用计数和垃圾回收 9. **标准库模块** - 使用 std 和 os 模块 10. **自定义模块** - 创建和使用自定义 JS 模块 ## 关键 API ### 初始化 ```c JSRuntime *rt = JS_NewRuntime(); JSContext *ctx = JS_NewContext(rt); js_std_add_helpers(ctx, argc, argv); ``` ### 执行 JavaScript ```c JSValue result = JS_Eval(ctx, "1 + 2", 5, "", JS_EVAL_TYPE_GLOBAL); ``` ### 注册 C 函数 ```c JSValue func = JS_NewCFunction(ctx, my_c_function, "funcName", argCount); JS_SetPropertyStr(ctx, global, "funcName", func); ``` ### 数据类型转换 ```c // C 到 JS JSValue val = JS_NewInt32(ctx, 42); JSValue str = JS_NewString(ctx, "Hello"); // JS 到 C double num; JS_ToFloat64(ctx, &num, js_value); const char *str = JS_ToCString(ctx, js_value); JS_FreeCString(ctx, str); ``` ### 内存管理 ```c JSValue val = JS_NewString(ctx, "test"); JSValue val2 = JS_DupValue(ctx, val); // 增加引用 JS_FreeValue(ctx, val); // 释放引用 JS_FreeValue(ctx, val2); // 最后一个引用被释放 ``` ### 异常处理 ```c JSValue exception = JS_GetException(ctx); if (!JS_IsUndefined(exception)) { // 处理异常 } JS_FreeValue(ctx, exception); ``` ## 项目结构 ``` quickjs-prj/ ├── yps-quickjs/ # QuickJS 库源码 │ ├── quickjs.c/h # 核心 API │ ├── quickjs-libc.c/h # 标准库扩展 │ └── CMakeLists.txt # 库构建配置 ├── main.c # 完整示例 ├── simple_demo.c # 简单示例 ├── CMakeLists.txt # 主项目构建配置 └── build/ # 构建输出目录 ├── lib/ # 静态库 └── bin/ # 可执行文件 ``` ## 集成到你的项目 在你的 CMakeLists.txt 中添加: ```cmake add_subdirectory(path/to/yps-quickjs) target_link_libraries(your_target PRIVATE ypqjs) target_include_directories(your_target PRIVATE path/to/yps-quickjs) ``` ## 注意事项 1. **栈大小**:Windows 上默认需要 8MB 栈大小 2. **编码**:源文件使用 UTF-8 编码以支持中文字符 3. **内存管理**:及时释放 JSValue 以避免内存泄漏 4. **异常处理**:执行 JS 代码后检查异常 5. **线程安全**:每个线程需要独立的 JSRuntime 和 JSContext