python3調用微軟js引擎ChakraCore

来源:https://www.cnblogs.com/pyAppMan/archive/2020/01/05/12153468.html
-Advertisement-
Play Games

有關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文檔借鑒,是自己一步一個腳印,爬坑爬出來的,好似盲人摸象。寫的不好,還請輕噴。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • The forgotten ideas in computer science-Joe Armestrong ...
  • 本系列筆記主要基於《深入理解Java虛擬機:JVM高級特性與最佳實踐 第2版》,是這本書的讀書筆記。 記憶體分配一般關註的是對象在堆上分配的情況,對象主要分配在新生代的Eden區中,如果啟用了本地線程分配緩衝,將按線程優先在TLAB上分配。少數情況下也會直接分配在老年代中,這取決於使用的垃圾收集器組合 ...
  • 0x00 抓包分析 簡單的搜索之後發現,很多參數都是登陸上面這個請求返回的值,這個請求在輸入完賬號游標到達密碼框時就會生成! 0x01 加密邏輯分析 搜索su=可以很快找到加密的位置,上圖看到e.su和e.sp都是由sinaSSOEncoder這個函數生成的,搜索sinaSSOEncoder發現就是 ...
  • 1.python 讀取Excel text.xlsx內容如下: 運行結果: 2.python 寫入Excel 運行結果: rw r r 1 root root 17920 8月 6 11:53 partitions.xls 3.python Excel寫入表內 user_zw.xls的內容: 查詢表 ...
  • 首先需要安裝三個包: 1.製作英文字母的詞雲 效果圖: 代碼實現: 其中,test.txt文件內容如下 2.製作中文的詞雲 效果圖: 代碼實現: 其中alice.txt文件內容: 1.png模板內容: 看著還挺像。 ...
  • 1.用python調用python腳本 另外一個python腳本b.py如下: 運行結果: 2.python調用shell方法os.system() shell腳本如下: 運行結果: 3.python調用shell方法os.popen() 運行結果: os.system.popen() 這個方法會打 ...
  • 1 #include<stdio.h> 2 #define N 5 3 main() 4 { 5 int a[N]; 6 int j, i,m; 7 for (i = 0; i < N; i++) 8 { 9 scanf("%d", a + i); 10 } 11 for (i = 0; i < N ...
  • Access Flags 占2個位元組,所以該位元組碼文件的訪問標誌是00 21,0x0021在 Access Flags 中是0x0020和0x0001的並集,表示 ACC PUBLIC與 ACC SUPER合併的結果。說明該類的聲明修飾是public並且繼承Object ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...