1

我正在使用 MacOSX 10.8.2 和最新的 xcode 和股票 python 解释器在 Mac 上开发。

这是我放入的一些代码fails.cpp

#include <iostream>

using namespace std;

extern "C" {

void mysort(long *data, long data2) {
    cout << hex << *data << ' ' << data2 << endl;
}

}

这是一些从我放入的python中调用它的代码fails.py

import ctypes

sort_dll = ctypes.CDLL("fails.dylib")
mysort = ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_long), ctypes.c_long)(sort_dll.mysort)

a = ctypes.c_long(0x987654321)
mysort(ctypes.byref(a), 0x123456789)

我编译并运行

c++ -arch x86_64 -o fails.o -c fails.cpp && g++ -o fails.dylib -dynamiclib fails.o && python fails.py

结果是:

987654321 23456789

为什么按值传递的 64 位整数被截断为 32 位?令人惊讶的是,指向 64 位 long 的指针没有被截断。

4

1 回答 1

1

我怀疑这是因为 Python ctypes 库已决定 c_long 的大小为 32 位。文档中有一些提示:

表示 C 有符号 int 数据类型。构造函数接受一个可选的整数初始化器;没有进行溢出检查。在 sizeof(int) == sizeof(long) 的平台上,它是 c_long 的别名

这段代码会告诉你 c_long 实际上有多大:

import ctypes
print ctypes.sizeof(ctypes.c_long())

指针引用的值不会被截断,因为 ctypes 只需编组指针本身。指针可能被截断,但这并不重要,因为无论如何高位都为零。ctypes 也可能决定 ctypes.POINTER 是 64 位的。你可以通过稍微修改上面的例子来发现。

于 2012-11-16T02:42:04.120 回答