Python 2 和 3 之间 ctypes 的差异
Posted
技术标签:
【中文标题】Python 2 和 3 之间 ctypes 的差异【英文标题】:Differences in ctypes between Python 2 and 3 【发布时间】:2011-11-07 13:10:51 【问题描述】:我有一个调用 DLL 的工作 python 2.7 程序。我正在尝试将脚本移植到 python 3.2。 DLL 调用似乎有效(即调用时没有错误),但返回的数据没有意义。
以防万一它有用: - 调用需要三个参数:两个 int(输入)和一个指向 ushort 数组的指针(输出)。
我尝试同时使用 python 和 numpy 数组都没有成功。
谁能列举 Python 2.7 和 3.2 在 ctypes 方面的区别?
提前致谢
编辑
这是一些示例代码。 DLL 是专有的,所以我没有代码。但我确实有 C 标头:
void example (int width, int height, unsigned short* pointer)
python代码是:
width, height = 40, 100
imagearray = np.zeros((width,height), dtype=np.dtype(np.ushort))
image = np.ascontiguousarray(imagearray)
ptrimage = image.ctypes.data_as(ct.POINTER(ct.c_ushort))
DLL.example(width, height, ptrimage)
这在 python 2.7 中有效,但在 3.2 中无效。
编辑 2
如果ctypes中的变化只是Cedric指出的那些,那么python 3.2不能工作是没有意义的。所以再次查看代码,我发现在我提到的函数之前调用了一个准备函数。签名是:
void prepare(char *table)
在 python 中,我通过以下方式调用:
table = str(aNumber)
DLL.prepare(table)
有没有可能是因为 Python 字符串处理的改变造成的?
【问题讨论】:
我完全不知道有什么不同。我想我们需要看看一些代码。 【参考方案1】:在 Python 2.7 中,默认情况下字符串是字节字符串。在 Python 3.x 中,它们默认为 unicode。尝试使用 .encode('ascii')
显式将您的字符串设置为字节字符串,然后再将其交给DLL.prepare
。
编辑:
#another way of saying table=str(aNumber).encode('ascii')
table = bytes(str(aNumber), 'ascii')
DLL.prepare(table)
【讨论】:
几年过去了,这个答案很有用!我还遇到了一个问题,我在 Python3 中使用了一个旧的 python 库,并且无法理解为什么代码不起作用。将传递给共享库的字符串更改为 ascii 后,一切正常!【参考方案2】:在我们的例子中,我们的代码如下所示:
addr = clib.some_function()
data = some_struct.from_address(addr)
这在 python 2 中有效,但在 python 3 中无效。结果证明不是 ctypes 有任何差异,而是内存布局的变化暴露了上面代码中的错误。在 python 2 中,返回的地址总是(偶然地)小到足以容纳在 C int(32 位)中,这是所有 ctypes 函数调用的默认返回类型。在 python 3 中,地址几乎总是太大,这导致指针地址在被强制为 int 时被破坏。
解决方法是将函数restype
设置为64位整数类型,保证能容纳整个地址,如:
clib.some_function.restype = c_longlong
或:
clib.some_function.restype = POINTER(some_struct)
【讨论】:
【参考方案3】:根据python文档,2.7和3.2之间的唯一变化is here
一种新类型,ctypes.c_ssize_t 代表 C ssize_t 数据类型。
在 2.7 中,还有一些其他的 modifications introduced :
ctypes 模块现在总是将 None 转换为 C NULL 指针 声明为指针的参数。 (由 Thomas Heller 更改;问题 4606.) 底层 libffi 库已更新到版本 3.0.9,包含针对不同平台的各种修复。 (更新者 马蒂亚斯·克洛泽;问题 8142。)
我不确定它会解释你的问题的原因......
【讨论】:
以上是关于Python 2 和 3 之间 ctypes 的差异的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 ctypes 将(非空)列表从 Python 传递到 C++?
[微软]有两个序列a,b,大小都为n,序列元素的值任意整数,无序; 要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小_利用排列组合思路解决_python版
Python 3.x ctype c_wchar_p 和 c_char_p 返回状态不同于 ctypes doc