c++ - 用 ctypes 包装简单的 c++ 示例;分段故障

标签 c++ python ctypes

我通过添加私有(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

段错误没有发生

  1. 在原始代码中
  2. 如果我删除 m 的打印但将其保留为变量
  3. 如果我将 m 替换为 bar() 中的任何固定数字。

我真的很困惑为什么会发生这种情况。由于这是学习 ctypes 的实验,因此我们将不胜感激。

最佳答案

如果您使用的是 64 位 Python,则需要定义 restypeargtypes。否则 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/

相关文章:

c++ - QSet 中的重复项

c++ - 如何在不使用 C++ 管理员权限的情况下设置 AD 属性值?

python - 插补后知道特征名称

python - ctypes float 垃圾返回

python从兄弟文件夹导入

python - 为什么可以在 python 3 中使用 ctypes 修改不可变字节对象?

c++ - 如何使用 ctypes 从 C++ 函数返回对象?

python - 逐行读取缓冲区内容

c++ - QWidget删除问题

C++ 和 SDL2 网格移动太快