【问题标题】:ctypes class member access segfaultingctypes 类成员访问 segfaulting
【发布时间】:2012-09-18 17:52:38
【问题描述】:

我对在 python 中使用 c++ 类很感兴趣。看着Calling C/C++ from python?,我决定试试ctypes。但是,当我尝试更改类成员的值时,会出现段错误。

这是一个重现我的问题的简单示例:

C/C++ 方面:

#include <iostream>

class Foo{
    private:
        int mValue;
    public:
        void bar(){
            std::cout << "Hello" << std::endl;
        }
        void setValue(int inValue) {
            mValue = inValue;
            std::cout << "Value is now: " << mValue << std::endl;
        }
        void setValue2() {
            mValue = 2;
            std::cout << "Value is now: " << mValue << std::endl;
        }
};

extern "C" {
    Foo* Foo_new(){ return new Foo(); }
    void Foo_bar(Foo* foo){ foo->bar(); }
    void Foo_setValue(Foo* foo, int v) { foo->setValue(v); }
    void Foo_setValue2(Foo* foo) { foo->setValue2(); }
}

代码在 OSX 上编译:

g++ -c -fPIC foo.cpp -o foo.o && g++ -shared -Wl -o libfoo.dylib  foo.o

python方面:

from ctypes import *
lib = cdll.LoadLibrary('./libfoo.dylib')

class Foo(object):
    def __init__(self):
        self.obj = lib.Foo_new()
    def bar(self):
        lib.Foo_bar(self.obj)
    def set(self, v):
        lib.Foo_setValue(self.obj, v);
    def set2(self):
        lib.Foo_setValue2(self.obj);

我可以毫无问题地调用 bar,但是如果我调用 set 或 set2 会出现段错误。

f = Foo()
f.bar()  # Ok
f.set(3) # Segfault

显然,我错过了一些东西。

【问题讨论】:

  • 具体来说,我使用了链接帖子中的确切编译参数:g++ -c -fPIC foo.cpp -o foo.og++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o,并加载了./libfoo.so
  • 刚刚在 Linux 机器上试了试,正如你所说,它可以工作。但是,在 OSX 10.7.4 和 10.6.8 上,我得到了段错误。似乎是特定于平台的问题。
  • 好像是这样。另外,我注意到您没有在 c++ 部分中处理分配给mValue 的内存。我知道这只是说明段错误的示例代码,但仍然如此。

标签: c++ python c ctypes


【解决方案1】:

使用以下解决了问题:

def __init__(self):
    lib.Foo_new.restype = c_void_p # Needed
    self.obj = lib.Foo_new()

def set(self, v):
    lib.Foo_setValue(c_void_p(self.obj), v) # c_void_p needed

仔细阅读,这似乎是一个 64 位指针问题。

【讨论】:

  • 您也可以使用lib.Foo_setValue.argtypes=[c_void_p,c_int] 来声明参数类型。这样您就不必在每次使用参数时都包装它们。
猜你喜欢
  • 2023-03-02
  • 2012-10-18
  • 1970-01-01
相关资源
最近更新 更多