传递给C++函数的 Python 整数作为使用 ctypes 的 long 会被截断

Python ints passed into C++ functions as longs using ctypes get truncated

本文关键字:long ctypes C++ 函数 Python 整数      更新时间:2023-10-16

我正在使用MacOSX 10.8.2在Mac上进行开发,其中包含最新的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 位长度的指针没有被截断。

我怀疑这是因为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。指针是 64 位。 您可以通过稍微修改上面的示例来找出答案。