python3调用微软js引擎ChakraCore
有关chakracore介绍请移步:https://github.com/microsoft/chakracore
使用案例github源码:https://github.com/pyappman/chakracore
本文主要讲下python调用chakracore.dll
参考文献有: 以及 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)
五、参考文献
使用案例github源码:https://github.com/pyappman/chakracore
本文主要讲下python调用chakracore.dll
参考文献有: 以及 https://bbs.125.la/forum.php?mod=viewthread&tid=14495171&highlight=chakracore
欢迎大家补充,没有太多的python文档借鉴,是自己一步一个脚印,爬坑爬出来的,好似盲人摸象。写的不好,还请轻喷。
上一篇: 消息中间件-消息的可靠性传递