ctypes/C++ 访问成员变量的段错误

2023-12-24

我对 python ctypes 模块并不陌生,但这是我第一次尝试将 C++、C 和 Python 组合到一个代码中。我的问题似乎非常相似在 Python 和 C++ 中使用 ctypes 时出现段错误 https://stackoverflow.com/questions/12142766/seg-fault-when-using-ctypes-with-python-and-c?lq=1,但是我似乎无法以同样的方式解决问题。

我有一个简单的 C++ 文件,名为Header.cpp:

#include <iostream>

class Foo{
   public:
      int nbits;
      Foo(int nb){nbits = nb;}
      void bar(){ std::cout << nbits << std::endl; }
};

extern "C" {
   Foo *Foo_new(int nbits){ return new Foo(nbits); }
   void Foo_bar(Foo *foo){ foo->bar(); }
}

我使用以下方法将其编译为共享库:

g++ -c Header.cpp -fPIC -o Header.o
g++ -shared -fPIC -o libHeader.so  Header.o

和一个简单的 Python 包装器,名为test.py:

import ctypes as C
lib = C.CDLL('./libHeader.so')

class Foo(object):
    def __init__(self,nbits):
        self.nbits = C.c_int(nbits)
        self.obj = lib.Foo_new(self.nbits)

    def bar(self):
        lib.Foo_bar(self.obj)

def main():
    f = Foo(32)
    f.bar()

if __name__ == "__main__":
    main()

我希望当我调用 test.py 时,我应该将数字 32 打印到屏幕上。然而,我得到的只是一个分段错误。如果我更改构造函数以返回堆栈上的类实例(即没有newcall),然后传递对象,程序按预期执行。另外,如果我改变bar方法中的Foo类,这样它就不会使用nbits会员,程序没有seg错误。

我对 C++ 的了解有限,但我可以在 C 和 C++ 中按预期创建此函数,但在 Python 中却不能,这一事实有点令人困惑。任何帮助将不胜感激。

Update:感谢下面的评论之一,问题已经解决。在这种情况下,需要为 C 函数显式声明 restype 和 argtypes。即以下内容被添加到 python 代码中:

lib.Foo_new.restype  = C.c_void_p
lib.Foo_new.argtypes = [C.c_int32]
lib.Foo_bar.restype  = None
lib.Foo_bar.argtypes = [C.c_void_p]

我会尝试以下操作:

extern "C"
{
    Foo *Foo_new(int nbits)
    {
        Foo *foo = new Foo(nbits);
        printf("Foo_new(%d) => foo=%p\n", nbits, foo);
        return foo;
    }
    void Foo_bar(Foo *foo)
    {
        printf("Foo_bar => foo=%p\n", foo);
        foo->bar();
    }
 }

看看是否有foo match.

另外,您可能希望查看 Boost.Python 来简化 C++ 对象的 Python 绑定的创建。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ctypes/C++ 访问成员变量的段错误 的相关文章

随机推荐