C++ code:
#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();
}
}
compile c++ via g++ test.cpp -shared -fPIC -o test.so
Python script:
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()
Here is what I get:
Hello C++!
Segmentation fault
I am pretty sure the parameters are passed to C++ class. I just want to know a way to call the function in a C++ class.
-
Use pybind11 perhaps?n. m. could be an AI– n. m. could be an AI2022年12月14日 05:47:22 +00:00Commented Dec 14, 2022 at 5:47
-
Have you tried to debug?David Feurle– David Feurle2022年12月14日 05:51:26 +00:00Commented Dec 14, 2022 at 5:51
1 Answer 1
Python's ctypes doesn't do a lot of heavy lifting for you. It assumes that the argument and return types for cdll functions are all int until proven otherwise. So while your C++ code knows it's returning a DemoClass*, Python is truncating that to an integer, and on modern 64-bit systems pointers don't fit into plain integers.
Since you don't plan to use this pointer in Python for anything other than calling DLL functions, we don't have to reconstruct our structure on the Python side. Instead, we can use void*, the type of pointers to arbitrary data. In Python, we call this type c_void_p.
At the top of your program, just after loading the DLL, consider
lib.DemoCpp.argtypes = (c_int, c_int)
lib.DemoCpp.restype = c_void_p
lib.DemoCppFunction.argtypes = (c_void_p,)
lib.DemoCppFunction.restype = None
(Note: We can get away without lines 1 and 4 here, since Python will happily assume integer argument types, and our DemoCppFunction doesn't return anything so we don't try to use its return value. But for consistency, we may as well be explicit.)
2 Comments
DemoClass* and DemoCppFunction will return something? like this: DemoCppFunction will modify the value of a and return. ``` DemoClass* DemoCppFunction(DemoClass* demo){ demo->DemoFunction(); demo->a = 100; return demo; } ``` And I want to get the modified instance in python ``` newDemo = f.demoFunction() print(newDemo.a) # I know this does not work. ```restype to c_void_p in Python.