ctypes/C ++ segfault访问成员变量 [英] ctypes/C++ segfault accessing member variables

查看:32
本文介绍了ctypes/C ++ segfault访问成员变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对python ctypes模块并不陌生,但这是我第一次尝试在一个代码中组合C ++,C和Python.我的问题似乎与 Seg错误类似当在Python和C ++中使用ctypes时,但是,我似乎无法以相同的方式解决问题.

I am no stranger to the python ctypes module, but this is my first attempt at combining C++, C and Python all in one code. My problem seems to be very similar to Seg fault when using ctypes with Python and C++, however I could not seem to solve the problem in the same way.

我有一个名为 Header.cpp 的简单C ++文件:

I have a simple C++ file called Header.cpp:

#include <iostream>

class Foo{
   public:
      int nbits;
      Foo(int nb){nbits = nb;}
      void bar(){ std::cout << nbits << std::endl; }
};

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

我使用以下命令将其编译为共享库:

which I compile to a shared library using:

g++ -c Header.cpp -fPIC -o Header.o
g++ -shared -fPIC -o libHeader.so  Header.o

和一个名为 test.py 的简单Python包装器:

and a simple Python wrapper called test.py:

import ctypes as C
lib = C.CDLL('./libHeader.so')

class Foo(object):
    def __init__(self,nbits):
        self.nbits = C.c_int(nbits)
        self.obj = lib.Foo_new(self.nbits)

    def bar(self):
        lib.Foo_bar(self.obj)

def main():
    f = Foo(32)
    f.bar()

if __name__ == "__main__":
    main()

我希望当我打电话给test.py时,我应该将数字32打印到屏幕上.但是,我得到的只是一个细分错误.如果我更改构造函数以在堆栈上返回类实例(即,无需进行 new 调用),然后传递该对象,则程序将按预期执行.另外,如果我更改 Foo 类中的 bar 方法,使其不使用 nbits 成员,则程序不会出现段错误.

I would expect that when I call test.py, I should get the number 32 printed to screen. However, all I get is a segmentation fault. If I change the constructor to return the class instance on the stack (i.e. without the new call) and then pass around the object, the program performs as expected. Also, if I change the bar method in the Foo class such that it does not use the nbits member, the program does not seg fault.

我对C ++的了解有限,但是我可以像预期的那样在C和C ++中实现此功能,而在Python中无法实现这一事实,这有点令人困惑.任何帮助将不胜感激.

I have an limited understanding of C++, but the fact that I can make this function as expected in C and in C++ but not in Python is a little confusing. Any help would be greatly appreciated.

更新:由于下面的评论之一,该问题已解决.在这种情况下,需要为C函数同时显式声明restype和argtypes.即以下代码已添加到python代码中:

Update: Thanks to one of the comments below, the problem has been solved. In this case, an explicit declaration of both restype and argtypes for the C functions was required. i.e the following was added to the python code:

lib.Foo_new.restype  = C.c_void_p
lib.Foo_new.argtypes = [C.c_int32]
lib.Foo_bar.restype  = None
lib.Foo_bar.argtypes = [C.c_void_p]

推荐答案

我会尝试以下操作:

extern "C"
{
    Foo *Foo_new(int nbits)
    {
        Foo *foo = new Foo(nbits);
        printf("Foo_new(%d) => foo=%p\n", nbits, foo);
        return foo;
    }
    void Foo_bar(Foo *foo)
    {
        printf("Foo_bar => foo=%p\n", foo);
        foo->bar();
    }
 }

查看 foo 的值是否匹配.

此外,您可能希望查看Boost.Python来简化C ++对象的Python绑定创建.

Also, you might want to look at Boost.Python to simplify creating Python bindings of C++ objects.

这篇关于ctypes/C ++ segfault访问成员变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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