在 Python 中导入 C++ 共享对象时出现分段错误
Segmentation fault when importing a C++ shared object in Python
我有以下共享对象:
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();
}
}
我编译的是:g++ -fPIC -shared -o MyLib.so MyLib.cpp
然后我将它与以下 Python 脚本一起使用:
script.py
import ctypes
lib = ctypes.cdll.LoadLibrary("./MyLib.so")
MyClass = lib.create()
lib.func(MyClass)
像这样,它工作得很好,但是如果我取消注释行 //var = 10;
,Python 就会出现分段错误 (Python 3.8)。每次对象 MyClass
对其局部变量之一进行更改时都会发生这种情况(除了在构造函数内部,它工作的地方)。看起来变量 var
的地址是错误的,并且在访问它时出现段错误。我尝试对 function
使用关键字“virtual”而不做任何更改,并且我尝试使用 dlfcn 在另一个 C++ 程序中导入共享对象,效果很好。知道哪里出了问题吗?
指针不一样:
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();
}
}
运行 我得到:
Returning: 0x7faab9c06580
Calling: 0xffffffffb9c06580
似乎某处存在符号扩展问题。
您需要告诉 python 正在传递的对象的类型,否则它认为它们是 int
并且会发生令人讨厌的事情:
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)
我有以下共享对象:
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();
}
}
我编译的是:g++ -fPIC -shared -o MyLib.so MyLib.cpp
然后我将它与以下 Python 脚本一起使用:
script.py
import ctypes
lib = ctypes.cdll.LoadLibrary("./MyLib.so")
MyClass = lib.create()
lib.func(MyClass)
像这样,它工作得很好,但是如果我取消注释行 //var = 10;
,Python 就会出现分段错误 (Python 3.8)。每次对象 MyClass
对其局部变量之一进行更改时都会发生这种情况(除了在构造函数内部,它工作的地方)。看起来变量 var
的地址是错误的,并且在访问它时出现段错误。我尝试对 function
使用关键字“virtual”而不做任何更改,并且我尝试使用 dlfcn 在另一个 C++ 程序中导入共享对象,效果很好。知道哪里出了问题吗?
指针不一样:
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();
}
}
运行 我得到:
Returning: 0x7faab9c06580
Calling: 0xffffffffb9c06580
似乎某处存在符号扩展问题。
您需要告诉 python 正在传递的对象的类型,否则它认为它们是 int
并且会发生令人讨厌的事情:
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)