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官方文档

posted @ 2014-07-08 11:43  fyter  阅读(3487)  评论(5编辑  收藏  举报