我通过添加私有(private)成员变量并在 bar()
函数中打印它来扩展此 answer 中提供的示例:
#include <iostream>
class Foo{
private:
double m;
public:
Foo() { m = 2.344; };
void bar(){
std::cout << "Hello, number is " << m << std::endl;
}
};
extern "C" {
Foo* Foo_new(){ return new Foo(); }
void Foo_bar(Foo* foo){ foo->bar(); }
}
ctypes
包装器未更改并且是:
from ctypes import *
lib = cdll.LoadLibrary('./libfoo.so')
class Foo(object):
def __init__(self):
self.obj = lib.Foo_new()
def bar(self):
lib.Foo_bar(self.obj)
f = Foo()
f.bar()
当我运行 python 代码时(在之前已经编译了 C++ 代码之后),我遇到了一个段错误,我已将其缩小到在 bar() 中打印
。 m
段错误没有发生
- 在原始代码中
- 如果我删除
m
的打印但将其保留为变量 - 如果我将
m
替换为bar()
中的任何固定数字。
我真的很困惑为什么会发生这种情况。由于这是学习 ctypes 的实验,因此我们将不胜感激。
最佳答案
如果您使用的是 64 位 Python,则需要定义 restype
和 argtypes
。否则 ctypes 默认将值转换为 32 位 C int
。
from ctypes import *
lib = CDLL('./libfoo.so')
lib.Foo_new.argtypes = []
lib.Foo_new.restype = c_void_p
lib.Foo_bar.argtypes = [c_void_p]
lib.Foo_bar.restype = None
这里是 2.7.5 的源链接,Modules/_ctypes/callproc.c:
对于 64 位 Windows,C long
是 32 位的,但在大多数其他 64 位平台上它是 64 位的。通过强制 int
,结果至少是一致的。
关于c++ - 用 ctypes 包装简单的 c++ 示例;分段故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17240621/