【问题标题】:Python ctypes misbehaves when a C function returns a dynamic array当 C 函数返回动态数组时,Python ctypes 行为异常
【发布时间】:2019-09-19 20:28:52
【问题描述】:

我正在为 Matlab 的动态库开发 Python 包装类,以便在 Python 中读取 Matlab MAT 文件,我遇到了一个我无法从 ctypes 接口解释的奇怪行为。

C 函数签名如下所示:

    const mwSize *mxGetDimensions(const mxArray *);

这里,mwSize 是重命名的size_tmxArray* 是一个不透明的指针。该函数返回 Matlab 数组的“形状”。返回的指针指向 size_t 数组,该数组内部存储在 mxArray 对象中,并且以 null 结尾(其大小通过另一个函数获得)。

为了从 Python 调用这个函数,我将库设置如下:

    libmx = ctypes.cdll.LoadLibrary('libmx.dll')
    libmx.mxGetDimensions.restype = ctypes.POINTER(ctypes.c_size_t)
    libmx.mxGetDimensions.argtypes = [ctypes.c_void_p]

VAR中获得mxArray*后,我调用了:

    dims = libmx.mxGetDimensions(VAR)
    print(dims[0],dims[1])

VAR 已知是二维的,形状为 (1, 13)(使用 C 程序验证),但我的 Python 代码在 c_ulonglong 中返回 (55834574849 0)... 结果在所有存储的变量中始终是垃圾在测试 MAT 文件中。

我做错了什么?其他使用 VAR 的库调用似乎工作正常,因此 VAR 指向有效对象。如上所述,在 C 程序中调用的 mxGetDimensions() 按预期工作。

任何意见将不胜感激!谢谢

【问题讨论】:

  • 嗯,实际上将55834574849 转换为十六进制给出了答案:) 55834574849 -> 0xD 0000 0001 所以看起来它是uint32_t 的数组。尝试将 restype 设置为 ctypes.POINTER(ctypes.c_uint32) 并告诉我们它是否有效。
  • @Neitsa - 美丽。就是这样。不过,很好奇 Python 和 C 调用中的差异是如何产生的。在我的 C 测试代码中,我验证了 size_t 确实是 uint64_t... 无论如何,谢谢! (如果您可以将其重新发布为答案,我会接受您的信用)

标签: python ctypes


【解决方案1】:

@Neitsa 在 OP 下的评论中解决了我的直接问题,对 libmx.dll 的进一步调查解决了 Python 和 C 版本之间的剩余差异。

因为 Matlab 的 libmx.dll 可以追溯到很长时间,因为它最初是在 32 位时代编写的,所以 DLL 包含多个版本的函数以实现向后兼容性。事实证明,const mwSize *mxGetDimensions(const mxArray *); 是该函数的最旧版本,并且相关的 C 头文件 (matrix.h) 具有行 #define mxGetDimensions mxGetDimensions_800 以使用其最新版本覆盖该函数。显然,Python 的 ctypes 不检查 C 头文件;所以,留给我筛选头文件以确定要使用哪个版本的函数。

最后,当我将代码更改为:

    libmx = ctypes.cdll.LoadLibrary('libmx.dll')
    libmx.mxGetDimensions_800.restype = ctypes.POINTER(ctypes.c_size_t)
    libmx.mxGetDimensions_800.argtypes = [ctypes.c_void_p]

    dims = libmx.mxGetDimensions_800(VAR)

所以,你有它:如果你要包装一个 3rd-party 动态/共享库,请彻底研究相关的头文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    相关资源
    最近更新 更多