繁体   English   中英

为什么我在这里遇到分段错误? [Python ctypes]

[英]Why do I get a segmentation fault here? [Python ctypes]

我对ctypes很新,我在下面的简单程序中遇到错误。

Foo.cpp中

class Foo {
public:
    int bar;
    Foo(int bar): bar(bar) {}
};

extern "C" {
    Foo * Foo_new(int bar) {
        return new Foo(bar);
    }

    int Foo_bar(Foo *foo) {
        return foo->bar;
    }
}

foo.py

import ctypes

libfoo = ctypes.CDLL('libfoo.so')


class Foo:
    def __init__(self, bar):
        self.foo = libfoo.Foo_new(bar)

    def bar(self):
        return libfoo.Foo_bar(self.foo)


foo = Foo(5)
print(foo.bar())

当我调用libfoo.Foo_bar(self.foo)时发生分段错误,但根据这个答案 ,我认为我需要做的就是通过self.foo做一个强引用,这样它就不会被垃圾收集了。

我的猜测是Foo是在CPP文件的堆栈中生成的,因此在进行函数调用后会立即擦除它。 无论如何,我该如何解决这个问题?

您必须显式地包装参数和返回类型,否则ctypes将假定某些可能或可能不起作用的任意默认值。 要将指针包装到类Foo ,我将使用指向void c_void_p的指针。 我不确定这是否是正确的方法,但似乎有效。

import ctypes

libfoo = ctypes.CDLL('libfoo.so')

libfoo.Foo_new.argtypes = [ctypes.c_int]
libfoo.Foo_new.restype = ctypes.c_void_p

libfoo.Foo_bar.argtypes = [ctypes.c_void_p]
libfoo.Foo_bar.restype = ctypes.c_int

class Foo:
    def __init__(self, bar):
        self.foo = libfoo.Foo_new(bar)

    def bar(self):
        return libfoo.Foo_bar(self.foo)

foo = Foo(5)
print(foo.bar())

我通常采用不同的途径通过使用SWIG生成Python扩展来将C ++代码与Python接口。 因此我会写一个文件test.h

class Foo {
public:
    int bar;
    Foo(int bar): bar(bar) {}
};

然后我会写一个SWIG接口文件test.i

%module test
%{
#include "test.h"
%}
%include "test.h"

然后我在终端执行

$ swig -python -c++ test.i
$ c++ -fpic -shared -I/usr/include/python2.7 test_wrap.cxx -o _test.so

然后我可以用Python脚本编写

from test import Foo
foo = Foo(5)
print foo.bar

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM