c++ - 只要使用 ctypes 的 long 被截断,Python 整数就会传递给 C++ 函数

标签 c++ python macos ffi

我在 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/

相关文章:

python - MTurk API : Unable to see my created HIT on dashboard

python - 尽管索引匹配,但 pd.IndexSlice 的 pd.Series 赋值会导致 NaN 值

c - 如何通过 c 中的命令行在 Xcode 中执行和编译程序,可执行文件在哪里?

mysql - 在 OSX El Capitan、RVM 上为旧版 Rails 应用程序安装 mysql gem - MySQL dmg/brew

c++ - QT "Tick"小部件循环

调用dll函数后未捕获C++异常

python - 使用 Python Pandas 对 csv 文件中的行进行排序

objective-c - 抓取一个被遮挡的窗口的屏幕截图

c++ - Sync_queue 类编译错误

c++ - IEEE-754 浮点计算、相等和缩小