2012-08-27 2 views
0

Linux 컴퓨터에서 ctypes를 사용하여 Python 2.7에서 C++ 라이브러리를 호출하여 실행하려고합니다. 잠시 동안 나는 장난감 예제 만 시도하고 있습니다. 이 스레드에서 주어진 예제를 읽고 복제 할 수있었습니다 : Calling C/C++ from python?. C++ 클래스 함수는 입력을받지 않습니다.Python 및 C++에서 ctypes를 사용할 때 Seg 오류가 발생했습니다.

다음 예제와 같이이 예제를 확장하려고합니다.

foo.cpp에

#include <iostream> 
#include <string> 
using namespace std; 

class Foo { 
public: 
    Foo(string name); 
    void bar(void); 
private: 
    string myName; 
}; 
Foo::Foo(string name) { 
    std::cout << "Entered constructor in C++" << std::endl; 
    myName = name; 
} 
void Foo::bar(void) { 
    std::cout << "Hello, this is " << myName << std::endl; 
} 

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

코드는 깨끗하게 g++ -c -fPIC foo.cpp -o foo.o 다음 g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o를 사용하여 컴파일합니다. 나는 다음 래퍼를 사용

,

fooWrapper.py는

from ctypes import cdll, c_char_p 
lib = cdll.LoadLibrary('./libfoo.so') 

class Foo(object): 
    def __init__(self,name): 
     self.name = name 
     self.obj = lib.Foo_new(c_char_p(name)) 
    def bar(self): 
     lib.Foo_bar(self.obj) 

내가 생성자에 문자열을 전달하고 있습니다 때문에, 나는 그것을 캐스팅 할 필요가 인상을 해요 c_char_p을 사용하십시오. 어쩌면 이것은 잘못된 것일 수 있습니다. 내가 파이썬 2.7의 코드를 실행하면

, 나는

Python 2.7.2 (default, Feb 27 2012, 18:28:19) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import fooWrapper as f 
>>> foo = f.Foo('somename') 
Segmentation fault 

그래서 나는 C++ 생성자 함수에 결코, 세그먼트 오류를 ​​얻을. 파이썬 코드에서 생성자 메서드에 self.name = name 행을 포함하는지 여부와 관계없이 동일한 문제가 발생합니다.

내가 뭘 잘못하고 있니? 감사.

+0

std :: string은 포인터의 typedef가 아니라 클래스입니다. 나는 100 % 확신 할 수는 없지만 캐릭터 포인터를 가져 와서 결함을 그렇게 구분하지 않는지보기 위해 Foo를 변경하려고합니다. std :: string과의 호환성을 유지하기 위해 어떻게 변경할지 모르겠다. – Wug

+0

파이썬에서'f.foo ('somename')'의'Foo' 생성자를 호출하고 있습니다. 파이썬 코드 대신'f.bar'를 쓰지 않았습니까? –

답변

0

extern "C"Foo_newstd::string 인수를 선언하지만 Python에서 호출 할 수있는 코드는 문자 포인터를받는 문자열을 포함하는 진정한 C 함수로 사용해야합니다. 특히 실제로 인터프리터에게 문자열을 문자 포인터로 변환하도록 알려주기 때문에 (즉, c_char_p 호출이하는 것입니다).

+0

고마워, 나는 그것을 고쳐 준 것처럼 보인다. 내'extern "C"'에서, 이제는 다른 모든 것들이 같은 'Foo * Foo_new (char * name) {return new Foo (name);}'를가집니다. 이 작동합니다. – xbot

관련 문제