I have the following shared object:
MyLib.cpp
#include <iostream>
class MyClass
{
public:
MyClass(){}
void function()
{
std::cout << "hello" << std::endl;
//var = 10;
}
private:
int var;
};
extern "C" {
MyClass* create()
{
return new MyClass();
}
void func(MyClass* myclass)
{
myclass->function();
}
}
That I compile with: g++ -fPIC -shared -o MyLib.so MyLib.cpp
I then use it with the following Python script:
script.py
import ctypes
lib = ctypes.cdll.LoadLibrary("./MyLib.so")
MyClass = lib.create()
lib.func(MyClass)
Like this, it works perfectly, but if I uncomment the line //var = 10;
, Python makes a segmentation fault (Python 3.8). This happens every time the object MyClass
makes a change to one of its local variable (except inside the constructor, where it works). It looks like the address of the variable var
is wrong and when accessing it, there is a segmentation fault. I tried using the keyword "virtual" for function
without any change, and I tried to import the shared object in another C++ program using dlfcn, which worked fine. Any idea what is wrong ?
The pointers are not the same:
extern "C" {
MyClass* create()
{
MyClass* myclass = new MyClass();
std::cerr << "Returning: " << myclass << "\n";
return myclass;
}
void func(MyClass* myclass)
{
std::cerr << "Calling: " << myclass << "\n";
myclass->function();
}
}
Running I get:
Returning: 0x7faab9c06580
Calling: 0xffffffffb9c06580
Looks like somewhere there was a sign extension issue.
You need to tell the python the type of the objects being passed around otherwise it thinks they are int
and nasty things happen:
import ctypes
lib = ctypes.cdll.LoadLibrary("./MyLib.so")
lib.create.restype = ctypes.c_void_p;
lib.func.argtypes = [ ctypes.c_void_p ];
MyClass = lib.create();
lib.func(MyClass)