[英]Import functions from dll (programmed in C++) into Python script when the dll has an embedded Python interpreter
我用C ++編寫了一個使用嵌入式Python解釋器的庫(dll)。 當C ++程序使用該庫時,在嵌入式解釋器中執行Python腳本可以正常工作。
如果我從Python程序調用dll的功能,則會遇到麻煩。 當dll通常通過調用Py_Initialize()啟動嵌入式解釋器時,已經有一個正在運行的解釋器(我可以通過調用Py_IsInitialized()進行測試)。 當我嘗試使用此解釋器時,程序崩潰。
重現該行為的最小示例:
dll的代碼:
#include "stdafx.h"
#include <Python.h>
extern "C" __declspec(dllexport)
int testIsInitialized()
{
return Py_IsInitialized();
}
extern "C" __declspec(dllexport)
void testRunSimpleString()
{
PyRun_SimpleString("print('test')");
}
Python腳本:
import ctypes
dll=ctypes.windll.LoadLibrary('pytest.dll')
# test if Python interpreter is initialized
print(dll.testIsInitialized())
# test if we can run a simple Python script
dll.testRunSimpleString()
輸出:
1
Traceback (most recent call last):
File "test_dll.py", line 9, in <module>
dll.testRunSimpleString()
OSError: exception: access violation reading 0x0000000000000010
我的主要問題是:如何從其他Python程序導入的c ++庫中執行Python代碼?
UPDATE
當我在testRunSImpleString()函數中獲取全局解釋器鎖(GIL)時,該示例將起作用。 我不明白為什么這是必要的。
ctypes
庫具有幾個類來加載不同類型的DLL。 兩個相關的類是:
ctypes.CDLL
(即C DLL)-用於加載使用標准C調用約定的DLL。 這包括定義extern "C"
C ++ DLL。 ctypes.PyDLL
與C DLL相似,但在函數調用期間未釋放Python GIL。 直接調用Python C API函數很有用。 加載使用Python C API的C ++ DLL(即Python.h
)時,請使用ctypes.PyDLL
:
import ctypes
dll = ctypes.PyDLL('pytest.dll')
# then do whatever
dll.testRunSimpleString.argtypes = []
dll.testRunSimpleString.restype = None
dll.testRunSimpleString()
PyDLL要記住的一件事是,由於解釋器已經在運行,因此您無需從C ++ API調用Py_Initialize()
或Py_Finalize()
/ Py_FinalizeEx()
。 您可以先檢查(並存儲) Py_IsInitialized()
來查看是否需要啟動/停止新的解釋器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.