简体   繁体   English

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

[英]Segmentation fault when importing a C++ shared object in Python

I have the following shared object:我有以下共享 object:

MyLib.cpp 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我编译的是: g++ -fPIC -shared -o MyLib.so MyLib.cpp

I then use it with the following Python script:然后我将它与以下 Python 脚本一起使用:

script.py脚本.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;像这样,它工作得很好,但如果我取消注释行//var = 10; , Python makes a segmentation fault (Python 3.8). , Python 产生分段错误(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).每次 object MyClass对其局部变量之一进行更改时都会发生这种情况(构造函数内部除外,它在其中工作)。 It looks like the address of the variable var is wrong and when accessing it, there is a segmentation fault.看起来变量var的地址是错误的,并且在访问它时出现了分段错误。 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.我尝试对function使用关键字“virtual”而不做任何更改,我尝试使用 dlfcn 在另一个 C++ 程序中导入共享的 object,效果很好。 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:您需要告诉 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM