我在 Mac 上使用 MacOSX 10.8.2 和最新的 xcode 以及常用的 python 解释器进行开发。
这是我放入fails.cpp
#include <iostream>
using namespace std;
extern "C" {
void mysort(long *data, long data2) {
cout << hex << *data << ' ' << data2 << endl;
}
}
这是我在 fails.py
中从 python 调用它的一些代码:
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 的指针没有被截断。
最佳答案
我怀疑这是因为 Python ctypes 库已决定 c_long 的大小为 32 位。 docs 中有一些提示:
表示 C 签名的 int 数据类型。构造函数接受一个可选的整数初始值设定项;没有进行溢出检查。 在 sizeof(int) == sizeof(long) 的平台上它是 c_long 的别名。
此代码将告诉您 c_long 实际上有多大:
import ctypes
print ctypes.sizeof(ctypes.c_long())
指针引用的值不会被截断,因为 ctypes 只需要编码指针本身。指针可能被截断了,但这并不重要,因为无论如何高位都为零。也有可能是 ctypes 决定 ctypes.POINTER 是 64 位的。稍微修改一下上面的例子就可以知道。
关于c++ - 只要使用 ctypes 的 long 被截断,Python 整数就会传递给 C++ 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13408993/