编译并使用QuickJS(C++项目)

我用的是QuickJS的分叉项目:https://github.com/quickjs-ng/quickjs,关于这个项目,详见我之前的介绍:推荐:QuickJS的分叉:QuickJS-NG

我直接用CMake-gui编译此项目,编译不能用MSVC的编译器,我用的是LLVM的CLang编译器,如下图所示:

详见:https://github.com/quickjs-ng/quickjs/issues/1  编译成功之后,你会得到qjs.lib,具体怎么在项目中用这个库,我就不多介绍了,下面介绍一下怎么在C++项目中使用QuickJS。

初始化QuickJS运行时:


JSContext* rt = JS_NewRuntime();
if (!rt) return;
JSRuntime* ctx = JS_NewContext(rt);
if (!ctx) {
    JS_FreeRuntime(rt);
    return;
}

JSContext是JavaScript脚本的运行上下文对象,它负责管理脚本执行相关的所有状态及作用域,

JSRuntime是JavaScript脚本的运行环境,它负责内存分配和垃圾回收。

多个 JSContext 可以共享同一个 JSRuntime,但它们之间是隔离的,不能直接访问对方的状态

加载JS脚本:


std::ifstream file("main.js");
std::string content((std::istreambuf_iterator<char>(file)), 
    std::istreambuf_iterator<char>());
JSValue val = JS_Eval(ctx, content.c_str(), 
    content.size(), 
    mainFilePath, 
    JS_EVAL_TYPE_MODULE);
if (JS_IsException(val)) {
    Console::Err(val);
    return;
}
JS_FreeValue(ctx, val);

这段代码的主要作用就是读main.js文件内的js脚本,并把脚本字符串交给QuickJS运行。

注意qjs.lib中是不包含console.log和setInterval这样的API的。所以你的在脚本中最好也不要有用这些API,不然会报错。

注册一个模块:

我们知道JavaScript在浏览器或Node.js里运行时,都有一些全局对象,比如:window,console等。

接下来我们就为QuickJS注册一个app对象,让这个对象公开一个openUrlByDefaultBrowser方法,预期可以通过这样的JavaScript脚本来打开一个浏览器网页:

app.openUrlByDefaultBrowser("https://www.baidu.com");
这是给QuickJS注册app对象的C++代码

auto app = JS_NewObject(ctx);
auto func = JS_NewCFunction(ctx, 
  &openUrlByDefaultBrowser, 
  "openUrlByDefaultBrowser", 
  1);
JS_SetPropertyStr(ctx, 
  app, 
  "openUrlByDefaultBrowser", 
  func);
JSValue globalObj = JS_GetGlobalObject(ctx);
JS_SetPropertyStr(ctx, globalObj, "app", app);
JS_FreeValue(ctx, globalObj);

C++接收并处理JavaScript的请求:

上述代码中&openUrlByDefaultBrowser就是我们的打开浏览器的C++方法,代码如下:

JSValue openUrlByDefaultBrowser(JSContext* ctx, 
    JSValueConst thisVal, 
    int argc, 
    JSValueConst* argv)
{
    const char* url = JS_ToCString(ctx, argv[0]);
    HINSTANCE result = ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
    JS_FreeCString(ctx, url);
    return JS::MakeVal(0, JS_TAG_UNDEFINED);
}

这个方法的第一个参数是这个JS方法的运行上下文,第二个参数是执行当前方法的JS对象,第三个参数是这个JS方法的参数数量,第四个参数是这个JS方法的参数数组。

我们这个方法返回了一个undefined对象,如果你想返回别的类型,比如字符串,可以通过这样的方法:


 return JS_NewString(ctx, "abc123");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liulun

如果文章真帮到了你,谢谢您打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值