1

我通过添加一个私有成员变量并在函数中打印它来扩展这个答案bar()中提供的示例:

#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++ 代码之后),我遇到了一个分段错误,我已经缩小到min的打印范围bar()

段错误没有发生

  1. 在原始代码中
  2. 如果我删除打印m但将其保留为变量
  3. 如果我mbar().

我真的很困惑为什么会发生这种情况。由于这是一个学习 ctypes 的实验,任何帮助将不胜感激。

4

1 回答 1

3

如果您使用的是 64 位 Python,则需要定义restypeand 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,Clong是 32 位的,但在大多数其他 64 位平台上它是 64 位的。通过强制int结果至少是一致的。

于 2013-06-21T18:53:03.417 回答