欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python3调用微软js引擎ChakraCore

程序员文章站 2022-03-07 15:37:12
有关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://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文档借鉴,是自己一步一个脚印,爬坑爬出来的,好似盲人摸象。写的不好,还请轻喷。