使用python ctypes和libc将void指针写入二进制文件 [英] Using python ctypes and libc to write void pointer to binary file

查看:114
本文介绍了使用python ctypes和libc将void指针写入二进制文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用python ctypes和libc与供应商提供的DLL文件进行接口。 DLL文件的目的是从相机获取图像。

I am using python ctypes and libc to interface with a vendor-provided DLL file. The purpose of the DLL file is to acquire an image from a camera.

图像获取运行似乎没有错误;我遇到的问题是访问数据。

The image acquisition appears to run without error; the issue I am having is accessing the data.

图像获取函数将ctypes.c_void_p用作图像数据的参数。

The image acquisition function takes a ctypes.c_void_p as an argument for the image data.

简化如下:

"""
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)。但是,它也具有与之关联的值。我假设这是存储数据的起始地址。

I do not fully understand exactly what the function is doing, because after I run the function, imageData.initial_readout appears to be a type 'long' (not even a ctypes.c_long: just 'long'). However, it also has a value associated with it. I'm assuming this is a starting address of where the data is stored.

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

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

My current approach for accessing the data is to use libc.fopen, libc.fwrite, libc.fclose as follows:

>>> 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 对应于16位像素的1024x1024数组。

where readoutstride = 2097152 corresponding to a 1024x1024 array of 16 bit pixels.

文件 output3.raw显示在Windows资源管理器中,但是它有0 KB,当我尝试使用打开它(例如,使用imag查看器)时说文件为空。

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

I see that fwrite returns a value of 0 (but should return a value of 1)

如果您对我在这里做错的事情有任何想法,我非常感谢。

If you have any ideas as to what I'm doing wrong here, I appreciate it immensely. Thank you in advance.

推荐答案

指定 argtypes restype

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)

这篇关于使用python ctypes和libc将void指针写入二进制文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆