Windows桌面或服务器环境下嵌入JavaScript支持,JSRT

很多人比较关注Google的JS V8 JavaScript引擎,确实Google最近很高调。但这个库在Windows下使用确实有点难度,即使在Linux嵌入,也需要下载gyp,编译安装,然后再下载v8,再编译,再嵌入,再就是……搞这些,你得跳墙,可谓学习成本与应用成本都比较高。

我不迷恋Google,喜欢一些Google的项目,比如angelproject,protobuf。

下一篇文章讨论V8与JSRT的性能

下面我来讲讲Windows Desktop环境嵌入JS脚本支持。在Windows环境,这真是一个宝贝,如果不考虑可移植性,绝对可以很好的替代Lua,因为它比Lua更高效,更易用,支持的开发环境也多。这是一篇中级文章,不详细介绍到参数如何使用,自己领悟。

微软为C++提供了非常方便的JS脚本接口(JavaScript Runtime Hosting, JSRT),以至于我了解了这个接口后,认为Lua的基于堆栈式接口实在是非常难用。微软为JSRT提供了完整的接口文档,但说明不够详尽,也提供了一个风格不太优雅的例子项目,还为C#进行了封装。微软也为JSRT提供了调试接口,但本人未使用,所以希望以后的文章有机会再进行讲解。

使用JSRT,需要两样东西,include <jsrt.h> 连接jsrt.lib,嗯,就是这么简单的前提。也希望你不要认为后面就很麻烦。

三行代码即可构建完整的JS运行环境。

JSRT的接口均使用Js前缀,并且返回统一的错误代码,正确运行返回JsNoError。

JS是基于对象的语言,所有函数应该都属于一个对象,我们注册到JS环境的函数/变量自然也属于一个对象——全局对象。

JSRT里的一起对象用C++操作时都是JsRef,可以用JsGetValueType获取类型。类型有JsString,JsFunction,JsNumber,JsError等。

JSRT当产生异常/错误时,可用JsGetAndClearException来获取并清理,取到的应该是JsError类型。

代码:

#include <jsrt.h>//别忘了link jsrt.lib

int main()

{

auto r = JsCreateRuntime(JsRuntimeAttributeNone, JsRuntimeVersion11, 0, &runtime);// 创建环境

r = JsCreateContext(runtime, 0, &context);// 创建上下文描述或者叫描述表

r = JsSetCurrentContext(context);// 把上面创建的设置为当前的

// 到这里,环境已经创建完成,可以执行脚本了

JsRef result;

r = JsRunScript(L"var value = 0;", 0, L"", &result);

}

函数支持

JsValueRef CALLBACK jsservice::log(JsValueRef callee, bool isConstructCall,

JsValueRef *arguments, unsigned short argumentCount, void *callbackState)

{

// arguments 参数列表,第一个为调用者

// argumentCount 参数数量

return JS_INVALID_REFERENCE;//如果没结果

}

// 将函数注册到JS环境中

// 注册函数需要一个全局对象作为参数,可以调用JsGetGlobalObject取到

bool reg_func(const wchar_t* name, JsNativeFunction function_pointer)

{

JsPropertyIdRef property_id;

auto ec = JsGetPropertyIdFromName(name, &property_id);

if (ec != JsErrorCode::JsNoError)

return false;

JsValueRef function;

ec = JsCreateFunction(function_pointer, 0, &function);

if (ec != JsErrorCode::JsNoError)

{

JsRelease(propertyId, 0);

return false;

}

ec = JsSetProperty(global_object, property_id, function, true);

if (ec != JsErrorCode::JsNoError)

{

JsRelease(property_id, 0);

JsRelease(function, 0);

return false;

}

return true;

}

注册到环境以后,就可以在脚本中调用这个函数了。

文章结束

以下是相关引用:

微软JSRT官方文档