2012-09-18 3 views
4

저는 파이썬에서 C++ 클래스를 사용하고자합니다. Calling C/C++ from python?을보고, 나는 ctypes를 시도하기로 결정했습니다. 그러나 클래스 멤버의 값을 변경하려고하면 segfault가 발생합니다. 여기 ctypes 클래스 멤버 액세스 segfaulting

내 문제를 재현하는 간단한 예입니다 :

는 C/C++ 쪽 :

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

파이썬 측 :

#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에 컴파일 할 수 있습니다 :

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를 호출하면 segfault가 발생합니다.

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

분명히, 나는 뭔가를 놓치고있다. 다음을 사용하여

+0

그것은 나를 위해 작동 –

+0

구체적으로, 나는 연결된 게시물에서 정확한 컴파일 매개 변수를 사용 :'g ++ -c -fPIC foo.cpp -o foo.o' 및'g ++ -shared -Wl, -soname, libfoo.so -o libfoo.so foo.o' 그리고'./libfoo.so'를 로딩합니다 –

+0

리눅스 박스에서 그냥 시도해 보았습니다. 그러나 OSX 10.7.4 및 10.6.8에서는 segfault가 발생합니다. 플랫폼 관련 문제인 것 같습니다. – jfdupuis

답변

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 비트 포인터 문제가 될 것으로 보인다.

+0

또한'lib.Foo_setValue.argtypes = [c_void_p, c_int]'를 사용하여 인수 유형을 선언 할 수 있습니다. 그런 다음 매번 인수를 사용할 필요가 없습니다. –