当使用ctypes与Python和C ++时的Seg故障 [英] Seg fault when using ctypes with Python and C++

查看:152
本文介绍了当使用ctypes与Python和C ++时的Seg故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Linux机器上尝试使用ctypes从Python 2.7调用C ++库。目前,我只是玩玩具例子。我阅读并能够复制此线程中提供的示例:从python调用C / C ++?。注意,C ++类函数不需要输入。



我试图扩展这个例子如下。



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< 你好,这是< myName<< std :: endl;
}

externC{
Foo * Foo_new(string name){return new Foo(name);}
void Foo_bar(Foo * foo){ foo> bar();}
}

c $ c> g ++ -c -fPIC foo.cpp -o foo.o 然后 g ++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo



fooWrapper.py

 来自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(默认,2012年2月27日,18:28:19)
[GCC 4.1.2 20080704(Red Hat 4.1.2-48)] on linux2
键入帮助,版权,信用或许可证了解更多信息。
>>>> import fooWrapper as f
>>>> foo = f.Foo('somename')
分段错误

C ++构造函数。我有同样的问题,无论是否在Python代码的构造函数方法中包含 self.name = name 行。



我做错了什么?感谢。

解决方案

在您的 externC c $ c> Foo_new 获取一个 std :: string 参数,但是对于可以从Python调用的代码, C函数,其中包括接收字符串的字符指针。特别是你实际上告诉解释器将你的字符串转换为一个字符指针(这是 c_char_p 调用)。


I am trying to get up and running with using ctypes to call C++ libraries from Python 2.7 on a Linux machine. For the moment, I'm just trying toy examples. I read and was able to replicate the example given in this thread: Calling C/C++ from python?. Note that the C++ class functions take no inputs.

I'm trying to extend this example as follows.

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();}
}

The code compiles cleanly using g++ -c -fPIC foo.cpp -o foo.o and then g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o.

I then use the following wrapper,

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)

Because I'm passing a string to the constructor, I'm under the impression that I need to cast it using c_char_p. Maybe this is wrong.

When I execute the code in Python 2.7, I get a segmentation fault,

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

So I never get into the C++ constructor function. I have the same problem whether or not I include the self.name = name line in the constructor method in the Python code.

What am I doing wrong? Thanks.

解决方案

In your extern "C" you declare Foo_new to take a std::string argument, however for the code to be callable from Python you have to make it a true C function, which include receiving strings a character pointers. Especially as you actually tells the interpreter to convert your string to a character pointer (that's what the c_char_p call does).

这篇关于当使用ctypes与Python和C ++时的Seg故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆