C++ 代码:
#include <iostream>
class DemoClass{
private:
int a, b;
public:
DemoClass(int v1, int v2){
a = v1;
b = v2;
}
void DemoFunction(){
std::cout << "Hello C++!" << std::endl;
std::cout << "output: a = " << a << ", b = " << b << std::endl;
}
};
extern "C" {
DemoClass* DemoCpp(int v1, int v2){
return new DemoClass(v1, v2);
}
void DemoCppFunction(DemoClass* demo){
demo->DemoFunction();
}
}
通过g++ test.cpp -shared -fPIC -o test.so编译c++
Python 脚本:
from ctypes import cdll
lib = cdll.LoadLibrary('./test.so')
class CppClass():
def __init__(self, v1: int, v2: int):
self.obj = lib.DemoCpp(v1, v2)
def demoFunction(self):
lib.DemoCppFunction(self.obj)
f = CppClass(2, 3)
f.demoFunction()
这是我得到的:
Hello C++!
Segmentation fault
我非常确定参数已传递给 C++ 类。我只是想知道如何在 C++ 类中调用该函数。
最佳答案
Python 的 ctypes
不会为您做很多繁重的工作。它假设 cdll 函数的参数和返回类型均为 int,除非另有证明。因此,虽然您的 C++ 代码知道它返回的是 DemoClass*
,但 Python 会将其截断为整数,而在现代 64 位系统上,指针不适合普通整数。
由于除了调用 DLL 函数之外,您不打算在 Python 中使用此指针进行任何其他操作,因此我们不必在 Python 端重建我们的结构。相反,我们可以使用void*
,即指向任意数据的指针类型。在Python中,我们称这种类型为c_void_p
.
在程序的顶部,加载 DLL 后,考虑
lib.DemoCpp.argtypes = (c_int, c_int)
lib.DemoCpp.restype = c_void_p
lib.DemoCppFunction.argtypes = (c_void_p,)
lib.DemoCppFunction.restype = None
(注意:这里我们可以不用第 1 行和第 4 行,因为 Python 很乐意采用整数参数类型,并且我们的 DemoCppFunction
不会返回任何内容,因此我们不会尝试使用它的返回值。但为了保持一致性,我们最好明确一下。)
关于python - 无法在Python中调用C++类函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74793982/