4

Pythonでc++クラスを使用することに興味があります。PythonからC/C ++を呼び出すことを検討していますか?、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);

バーは問題なく呼び出すことができますが、setまたはset2を呼び出すとセグメンテーション違反が発生します。

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

明らかに、私は何かが欠けています。

4

1 に答える 1

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ビットポインタの問題のようです。

于 2012-09-19T00:39:59.877 に答える