这是一篇非常老的帖子,可能原作者已经找到了解决方案,但由于还没有人提供有效的示例,我会尝试并希望能帮助像我一样遇到同样问题的人。
由于原作者没有具体说明,我将限制我的回答在Windows上,虽然Linux的解决方案很简单。我将尝试提供一个最小化的工作示例来复现所讨论的代码。
步骤1)从C++代码(单个文件)开始。
class Test{
private:
int n;
public:
Test(int k){
n=k;
}
void setInt(int k){
n = k;
}
int getInt(){
return n;
}
};
extern "C"
{
__declspec(dllexport) Test* init(int k) {return new Test(k);}
__declspec(dllexport) void setInt(Test *self, int k) {self->setInt(k);}
__declspec(dllexport) int getInt(Test *self) {return self->getInt();}
}
第二步) 编译DLL共享库。例如,从您的工作目录:
g++ -shared mytest.cpp -o libtest.dll
第三步) 创建包装器Python文件:
import ctypes
import platform
mode = dict(winmode=0) if platform.python_version() >= '3.8' else dict()
lib = ctypes.CDLL('./libtest.dll', **mode)
class Test(object):
def __init__(self, val: int):
lib.init.argtypes = [ctypes.c_int]
lib.init.restype = ctypes.c_void_p
lib.setInt.argtypes = [ctypes.c_void_p, ctypes.c_int]
lib.setInt.restype = ctypes.c_void_p
lib.getInt.argtypes = [ctypes.c_void_p]
lib.getInt.restype = ctypes.c_int
self.obj = lib.init(val)
def setInt(self, n):
lib.setInt(self.obj, n)
def getInt(self):
return lib.getInt(self.obj)
T1 = Test(12)
print(T1.getInt())
T1.setInt(32)
print(T1.getInt())
步骤4)运行代码
当我使用4个不同的Python版本运行脚本时,以下是我的结果:
PS D:\Desktop\mytest> py -3.7 .\mytest.py
12
32
PS D:\Desktop\mytest> py -3.8 .\mytest.py
12
32
PS D:\Desktop\mytest> py -3.9 .\mytest.py
12
32
PS D:\Desktop\mytest> py -3.10 .\mytest.py
Traceback (most recent call last):
File "D:\Desktop\mytest\mytest.py", line 7, in <module>
lib = ctypes.CDLL('./libtest.dll', **mode)
File "D:\Python\3102\lib\ctypes\__init__.py", line 374, in __init__
self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'D:\Desktop\mytest\libtest.dll' (or one of its dependencies). Try using the full path with constructor syntax.
在最后一种情况下,我已经尝试了完整路径,但仍然出现相同的错误。
我正在运行Windows 10 64位,并使用MinGW64中的g ++ 8.1.0进行编译。
评论:
我的答案基于
此处,
此处和
此处提供的解决方案。
当Python和编译器(g ++)架构不匹配(即32位或64位)时,常见问题会出现。