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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM