2012-08-27 72 views
0

我正在嘗試啓動並使用ctypes在Linux機器上從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。也許這是錯誤的。

當我在Python 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++構造函數。無論我在Python代碼中的構造函數方法中是否包含self.name = name行,我都遇到同樣的問題。

我在做什麼錯?謝謝。

+0

std :: string不是指向某個指針的typedef,而是一個類。我不是100%肯定的,但是我會嘗試改變你的Foo採取一個字符指針,看看它是否不以這種方式分段錯誤。我不知道你會如何改變它以保持與std :: string的兼容性,但我確信這是一種方法。 – Wug

+0

你正在從python調用f.Foo('somename')'中的'Foo'構造函數。你不是從你的Python代碼中執行'f.bar'嗎? –

回答

0

在您的extern "C"中,您聲明Foo_new採用std::string參數,但是要從Python調用代碼,必須使其成爲真正的C函數,其中包括接收字符串的字符指針。特別是當你實際上告訴解釋器將你的字符串轉換爲字符指針(這就是c_char_p調用的作用)。

+0

謝謝,我似乎修復了它。在我的'extern「C''中,我現在有了'Foo * Foo_new(char * name){return new Foo(name);}'和其他所有內容相同。這工作。 – xbot