2012-08-27 46 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