在Python中导入C++共享对象时出现分段错误

我有以下共享对象:

我的库文件

#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 脚本一起使用:

脚本文件

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)


以上是在Python中导入C++共享对象时出现分段错误的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>