使用python ctypes和libc将void指针写入二进制文件

我使用python ctypes和libc与供应商提供的DLL文件进行交互. DLL文件的目的是从相机获取图像.

图像采集似乎没有错误地运行;我遇到的问题是访问数据.

图像采集功能将ctypes.c_void_p作为图像数据的参数.

简化如下:

"""
typedef struct AvailableData
{
    void* initial_readout;
    int64 readout_count;
} imageData;
"""

class AvailableData(ctypes.Structure):
    _fields_ = [("initial_readout", ctypes.c_void_p), 
                ("readout_count", ctypes.c_longlong)]

"""
Prototype
Acquire(
CamHandle                 camera,
int64                       readout_count,
int                       readout_time_out,
AvailableData*         available,
AcquisitionErrorsMask* errors );
"""

>>> imageData = AvailableData()
>>> Acquire.argtypes = CamHandle, ctypes.c_longlong, ctypes.c_int, 
         ctypes.POINTER(AvailableData), ctypes.POINTER(AcquisitionErrorsMask)
>>> Acquire.restype = ctypes.c_void_p

>>> status = Acquire(camera, readout_count, readout_time_out, imageData, errors)

我并不完全理解函数正在做什么,因为在我运行函数之后,imageData.initial_readout似乎是一个’long’类型(甚至不是ctypes.c_long:只是’long’).但是,它也有与之相关的值.我假设这是存储数据的起始地址.

>>> type(imageData.initial_readout)
<type 'long'>
>>> imageData.initial_readout
81002560L

我目前访问数据的方法是使用libc.fopen,libc.fwrite,libc.fclose,如下所示:

>>> libc = ctypes.cdll.msvcrt

>>> fopen = libc.fopen
>>> fwrite = libc.fwrite
>>> fclose = libc.fclose
>>> fopen.argtypes = ctypes.c_char_p, ctypes.c_char_p
>>> fopen.restype = ctypes.c_void_p

>>> fopen.restype = ctypes.c_void_p
>>> fwrite.argtypes = ctypes.c_void_p, ctypes.c_size_t, ctypes.c_size_t, ctypes.c_void_p
>>> fwrite.restype = ctypes.c_size_t

>>> fclose = libc.fclose
>>> fclose.argtypes = ctypes.c_void_p,
>>> fclose.restype = ctypes.c_int

>>> fp = fopen('output3.raw', 'wb')
>>> print 'fwrite returns: ',fwrite(ctypes.c_void_p(imageData.initial_readout), readoutstride.value, 1, fp)
fwrite returns:  0
>>> fclose(fp)

其中readoutstride = 2097152对应于1024×1024的16位像素阵列.

文件“output3.raw”显示在Windows资源管理器中,然而,它有0千字节,当我尝试打开它时(例如使用图像浏览器),它表示文件为空.

我看到fwrite返回值0(但应返回值1)

如果你对我在这里做错了什么有任何想法,我非常感激.先感谢您.

解决方法:

指定argtypes,重定义函数.

import ctypes

libc = ctypes.windll.msvcrt

fopen = libc.fopen
fopen.argtypes = ctypes.c_char_p, ctypes.c_char_p,
fopen.restype = ctypes.c_void_p

fwrite = libc.fwrite
fwrite.argtypes = ctypes.c_void_p, ctypes.c_size_t, ctypes.c_size_t, ctypes.c_void_p
fwrite.restype = ctypes.c_size_t

fclose = libc.fclose
fclose.argtypes = ctypes.c_void_p,
fclose.restype = ctypes.c_int

fp = fopen('output3.raw', 'wb')
fwrite('Hello', 5, 1, fp)
fclose(fp)
上一篇:linux-libc源代码中的open()是从哪里链接的?


下一篇:Android静态链接与针对glibc的动态链接