有關ChakraCore介紹請移步:https://github.com/Microsoft/ChakraCore 使用案例GitHub源碼:https://github.com/pyAppman/ChakraCore 本文主要講下python調用ChakraCore.dll 參考文獻有:https ...
有關ChakraCore介紹請移步:https://github.com/Microsoft/ChakraCore
使用案例GitHub源碼:https://github.com/pyAppman/ChakraCore
本文主要講下python調用ChakraCore.dll
參考文獻有:https://xz.aliyun.com/t/2450 以及 https://bbs.125.la/forum.php?mod=viewthread&tid=14495171&highlight=ChakraCore
python是解釋性語言,網上能搜到的基本都是C、C#、C++、易語言的ChakraCore使用,並沒有python使用方法,參考了上面大佬們的相關介紹使用以及官方文檔,寫瞭如下可以成功調用的python例子。之所以寫這個是因為:第一,暫目前python用於執行js的工具有node,pyv8,js2py,windows系統下的com組件,node性能不好,v8不夠全安裝費勁不說,對python2更友好,js2py運行小js還可以,大了就不行了,com不夠全面比不上node內置的js函數,也不能跨平臺,ChakraCore綜合了node的全面跟v8的性能,還能跨平臺。第二、網上也有不少關於ChakraCore的文章,但是沒有python的,而易語言,C,C++這些並不是解釋性語言,很多方面跟python不一樣。第三、自己能力有限,過程中爬了很多坑,好似盲人過河,也算是想給其他有興趣的人一點幫助
一、準備工具
python解釋器,本人用的32位python3.6.x,其他版本也可以,但是務必用32位,跟dll有關原因不多做說明。
封裝的 ChakraCore.dll文件,源文件網上有,可以自行搜索下載,也可以https://github.com/pyAppman/ChakraCore上下載。
二、ChakraCore的部分方法(按順序執行)
1、JsCreateRuntime(文檔:https://github.com/microsoft/ChakraCore/wiki/JsCreateRuntime)
// 創建完整的JavaScript執行環境
2、JsCreateContext(文檔:https://github.com/microsoft/ChakraCore/wiki/JsCreateContext)
// 創建一個執行js的上下文環境
3、JsSetCurrentContext(文檔:https://github.com/microsoft/ChakraCore/wiki/JsSetCurrentContext)
// 表示一個擁有和別的execution contexts不同的JavaScript全局對象JavaScript的執行環境。
4、JsRunScript(文檔:https://github.com/microsoft/ChakraCore/wiki/JsRunScript)
// 執行js
5、JsGetValueType(文檔:https://github.com/microsoft/ChakraCore/wiki/JsGetValueType)
// 獲取返回值類型(整型,字元串型,列表,字典等)
6、JsConvertValueToString(文檔:https://github.com/microsoft/ChakraCore/wiki/JsConvertValueToString)
// 使用標準JavaScript語義將值轉換為字元串。
7、JsStringToPointer(文檔:https://github.com/microsoft/ChakraCore/wiki/JsStringToPointer)
// 檢索字元串值的字元串指針。
8、JsDisposeRuntime(文檔:https://github.com/microsoft/ChakraCore/wiki/JsDisposeRuntime)
// 處理runtime,類似於釋放
三、附上實戰代碼:
1、載入dll,初始化數據
def __init__(self): self.source = '' self.dll = windll.LoadLibrary('ChakraCore.dll') self.init_source = '''(function(){%s;return %s})()''' self.count = 0 self.result = c_wchar_p('') self._runtime = c_long(0) self._context = c_long(0) self._result = c_long(0) self._type = c_long(0) self._res_ptr = c_long(0) self._length_ptr = c_long(0)
2、創建所需環境
def create_runtime(self): return self.dll.JsCreateRuntime(0, None, pointer(self._runtime)) def create_context(self): return self.dll.JsCreateContext(self._runtime, pointer(self._context)) def set_current_context(self): return self.dll.JsSetCurrentContext(self._context)
3、組合js代碼
def compile(self, source): self.source = source
4、執行js並獲取結果
def run(self, func, *args): if not self._runtime: self.create_runtime() self.create_context() self.set_current_context() target = '{name}{arg}'.format(name=func, arg=args) js = self.init_source % (self.source, target) self.count += 1 _run = self.dll.JsRunScript(c_wchar_p(js), self.count, c_wchar_p(''), pointer(self._result)) if _run: self.dispose() return 'JsRunScript Error!', False return_type = self.dll.JsGetValueType(self._result, pointer(self._type)) if return_type: self.dispose() return 'Js Return Type Error!', False if self._type.value == JsValueType_JsArray: self.dispose() return 'List wait', False if self.dll.JsConvertValueToString(self._result, pointer(self.result)): self.dispose() return 'JsConvertValueToString Error', False str_ptr = c_wchar_p('') u_ptr = c_int(0) res = self.dll.JsStringToPointer(self.result, pointer(str_ptr), pointer(u_ptr)) if res: self.dispose() return 'JsStringToPointer Error', False else: # print(str_ptr.value) # self.dispose() return str_ptr.value, True
5、釋放runtime
def dispose(self): # self.dll.JsSetCurrentContext(0) self.result = c_wchar_p('') self.count = 0 self.dll.JsDisposeRuntime(self._runtime) def __exit__(self, exc_type, exc_val, exc_tb): self.result = c_wchar_p('') self.count = 0 self.dll.JsDisposeRuntime(self._runtime)
四、所有源碼如下:

1 from ctypes import * 2 3 JsValueType_JsUndefined = 0 # 公開,該值是未定義的值。 4 JsValueType_JsNull = 1 # 公開,值為空值。 5 JsValueType_JsNumber = 2 # 公開,該值是JavaScript數值。 6 JsValueType_JsString = 3 # 公開,該值是JavaScript字元串值。 7 JsValueType_JsBoolean = 4 # 公開,該值是JavaScript布爾值。 8 JsValueType_JsObject = 5 # 公開,該值是JavaScript對象值。 9 JsValueType_JsFunction = 6 # 公開,該值是JavaScript函數對象值。 10 JsValueType_JsError = 7 # 公開,該值是JavaScript錯誤對象值。 11 JsValueType_JsArray = 8 # 公開,該值是JavaScript數組對象值。 12 JsValueType_JsSymbol = 9 # 公開,該值是JavaScript符號值。 13 JsValueType_JsArrayBuffer = 10 # 公開,該值是JavaScriptArrayBuffer對象值。 14 JsValueType_JsTypedArray = 11 # 公開,該值是JavaScript類型的數組對象值。 15 JsValueType_JsDataView = 12 # 公開,該值是JavaScriptDataView對象值。 16 17 18 class ChakraCore: 19 20 def __init__(self): 21 self.source = '' 22 self.dll = windll.LoadLibrary('ChakraCore.dll') 23 self.init_source = '''(function(){%s;return %s})()''' 24 self.count = 0 25 self.result = c_wchar_p('') 26 self._runtime = c_long(0) 27 self._context = c_long(0) 28 self._result = c_long(0) 29 self._type = c_long(0) 30 self._res_ptr = c_long(0) 31 self._length_ptr = c_long(0) 32 33 def compile(self, source): 34 self.source = source 35 36 def create_runtime(self): 37 return self.dll.JsCreateRuntime(0, None, pointer(self._runtime)) 38 39 def create_context(self): 40 return self.dll.JsCreateContext(self._runtime, pointer(self._context)) 41 42 def set_current_context(self): 43 return self.dll.JsSetCurrentContext(self._context) 44 45 def value(self, value): 46 if value == JsValueType_JsNumber: 47 self.result = c_float(0) 48 elif value == JsValueType_JsString: 49 self.result = c_wchar_p('') 50 if self.dll.JsConvertValueToString(self._result, pointer(self.result)): 51 return 'JsConvertValueToString Error' 52 str_ptr = c_wchar_p('') 53 u_ptr = c_int(0) 54 res = self.dll.JsStringToPointer(self.result, pointer(str_ptr), pointer(u_ptr)) 55 if res: 56 return 'JsStringToPointer Error' 57 else: 58 return str_ptr.value 59 elif value == JsValueType_JsArray: 60 self.result = (c_wchar * 10)() 61 elif value == JsValueType_JsObject: 62 self.result = {} 63 else: 64 self.result = None 65 66 def run(self, func, *args): 67 if not self._runtime: 68 self.create_runtime() 69 self.create_context() 70 self.set_current_context() 71 72 target = '{name}{arg}'.format(name=func, arg=args) 73 js = self.init_source % (self.source, target) 74 self.count += 1 75 _run = self.dll.JsRunScript(c_wchar_p(js), self.count, c_wchar_p(''), pointer(self._result)) 76 if _run: 77 self.dispose() 78 return 'JsRunScript Error!', False 79 return_type = self.dll.JsGetValueType(self._result, pointer(self._type)) 80 if return_type: 81 self.dispose() 82 return 'Js Return Type Error!', False 83 if self._type.value == JsValueType_JsArray: 84 self.dispose() 85 return 'List wait', False 86 if self.dll.JsConvertValueToString(self._result, pointer(self.result)): 87 self.dispose() 88 return 'JsConvertValueToString Error', False 89 str_ptr = c_wchar_p('') 90 u_ptr = c_int(0) 91 res = self.dll.JsStringToPointer(self.result, pointer(str_ptr), pointer(u_ptr)) 92 if res: 93 self.dispose() 94 return 'JsStringToPointer Error', False 95 else: 96 # print(str_ptr.value) 97 # self.dispose() 98 return str_ptr.value, True 99 100 def dispose(self): 101 # self.dll.JsSetCurrentContext(0) 102 self.result = c_wchar_p('') 103 self.count = 0 104 self.dll.JsDisposeRuntime(self._runtime) 105 106 def __exit__(self, exc_type, exc_val, exc_tb): 107 self.result = c_wchar_p('') 108 self.count = 0 109 self.dll.JsDisposeRuntime(self._runtime)View Code
五、參考文獻
使用案例GitHub源碼:https://github.com/pyAppman/ChakraCore
本文主要講下python調用ChakraCore.dll
參考文獻有:https://xz.aliyun.com/t/2450 以及 https://bbs.125.la/forum.php?mod=viewthread&tid=14495171&highlight=ChakraCore
歡迎大家補充,沒有太多的python文檔借鑒,是自己一步一個腳印,爬坑爬出來的,好似盲人摸象。寫的不好,還請輕噴。