quickjs是一个C++实现的轻量级javascript解析引擎,可以嵌入到C++程序中,实现C++和js代码的交互。
以下基于quickjs-ng这一社区分支实现样例代码演示利用quickjs编写程序进行C++和js互相调用,支持linux和windows。
代码结构
quickjs_demo
- quickjs-0.5.0
- main.cpp # C++主执行程序
- main.js # js执行程序
- sample.hpp # C++模块代码,供js调用
- sample.js # js模块代码,供C++调用
- CMakeLists.txt
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(quickjs_demo)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (WIN32)
add_definitions(
-D_CRT_SECURE_NO_WARNINGS
-D_WINSOCK_DEPRECATED_NO_WARNINGS
)
elseif (UNIX)
add_compile_options(
-fPIC
-O3
)
endif()
add_subdirectory(./quickjs-0.5.0)
include_directories(./quickjs-0.5.0)
# build host executable
file(GLOB SRC
main.cpp
)
add_executable(${PROJECT_NAME} ${SRC})
target_link_libraries(${PROJECT_NAME}
qjs
pthread
)
基本原理为
- C++调用js:在C++中启动js运行时,加载js代码执行,可以返回js执行结果在C++中继续处理
- js调用C++:仍然在C++中启动js运行时,将C++定义的代码模块注册,加载js代码执行,调用注册好的C++模块,返回的结果可以在js中继续处理
基于这样的机制,就可以做到在C++的程序框架中C++与js双向交互,实现很多纯C++或者纯js达不到的效果,例如代码热更新以及安全隔离,这种机制目前其实在金融数据分析系统和游戏引擎中广泛使用。
C++调用js
sample.js
const a = 3;
const b = 5;
function my_func(x, y, text)
{
// the input params type, x is int, y is double, text is string, return z is double
// console.log("my_func with params:", x, y, text);
let z = x * y + (b - a);
return z;
}
C++代码
void cpp_call_js_test()
{
std::cout << "--- cpp call js test ---" << std::endl;
// init js runtime and context
JSRuntime* rt = JS_NewRuntime();
JSContext* ctx = JS_NewContext(rt);
// define global js object
JSValue global_obj = JS_GetGlobalObject(ctx);
// load js script
std::string js_file = "./sample.js";
std::ifstream in(js_file.c_str());
std::ostringstream sin;
sin << in.rdbuf();
std::string script_text = sin.str();
std::cout << "script text: " << std::endl;
std::cout << script_text << std::endl;
// run script
std::cout << "script run: " << std::endl;
JSValue script = JS_Eval(ctx