【发布时间】:2019-09-19 20:28:52
【问题描述】:
我正在为 Matlab 的动态库开发 Python 包装类,以便在 Python 中读取 Matlab MAT 文件,我遇到了一个我无法从 ctypes 接口解释的奇怪行为。
C 函数签名如下所示:
const mwSize *mxGetDimensions(const mxArray *);
这里,mwSize 是重命名的size_t,mxArray* 是一个不透明的指针。该函数返回 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... 无论如何,谢谢! (如果您可以将其重新发布为答案,我会接受您的信用)