使用Python Ctypes将结构指针传递给DLL函数

我正在尝试使用Python ctypes访问DLL文件中的函数。提供的功能说明如下。


Prototype: Picam_ConnectDemoCamera( PicamModel model,

                                    const pichar* serial_number,

                                    PicamCameraID* id )


Description: Virtually connects the software-simulated 'model' with 'serial_number'

and returns the camera id in `_id_`

Notes: `_id_` is optional and can be null

该函数引用DLL中定义的一些变量类型。接下来介绍这些变量


PicamModel

Type: enum

Description: The camera model.


PicamCameraID

Type: Struct

- PicamModel model: _model_ is the camera model

- PicamComputerInterface computer_interface: computer_interface is the method of

communication

- pichar sensor_name [PicamStringSize_SensorName]: sensor_name contains the name of

the sensor in the camera

- pichar serial_number [PicamStringSize_SerialNumber]: serial_number contains the

unique serial number of the camera

请注意,在提供的头文件之一中定义了“ pichar”,如下所示:


typedef          char   pichar; /* character native to platform   

这似乎很简单,但是由于某种原因对我来说却没有解决。

我的理解如下:我向函数传递了三个变量:

1)a model,实际上是一个enum。有人告诉我python ctypes本质上不支持枚举,因此我将一个整数2传递给它,该整数映射到特定的模型类型。

2)指向序列号的指针(我可以弥补这一点:任意字符串)

3)指向的指针PicamCameraID,该指针是DLL中定义的基于该struct类型的变量类型

读完SO之后,我找到了一些很好的起点,但是仍然运气不佳。到目前为止,这是我最好的镜头

def pointer(x):

      PointerToType = ctypes.POINTER(type(x))

      ptr = ctypes.cast(ctypes.addressof(x), PointerToType)

      return ptr


class PicamCameraID(ctypes.Structure):

      pass

PicamCameraID._fields_=[("model",ctypes.c_int),

                    ("computer_interface",ctypes.c_int),

                    ("sensor_name",ctypes.c_char_p),

                    ("serial_number",ctypes.c_char_p)]


myid = PicamCameraID()

model = ctypes.c_int(2)

serialnum = ctypes.c_char_p('asdf')

print picam.Picam_ConnectDemoCamera(model, pointer(serialnum), ctypes.byref(myid))

如您所愿,我正在尝试创建PicamCameraID与DLL中定义的结构相对应的变量类型。我的直觉是使用ctypes.pointer命令传递函数参数时参考,但我发现适应症使用ctypes.byref,而不是其他地方

qq_花开花谢_0
浏览 198回答 2
2回答

江户川乱折腾

您对PicamCameraID结构的定义不正确:sensor_name并且serial_number是arrays:"""struct PicamCameraID {  PicamModel             model;  PicamComputerInterface computer_interface;  pichar                 sensor_name[PicamStringSize_SensorName];  pichar                 serial_number[PicamStringSize_SerialNumber]; };"""import ctypes as cPicamStringSize_SensorName = PicamStringSize_SerialNumber = 64PicamModel = PicamComputerInterface = c.c_intpichar = c.c_charclass PicamCameraID(c.Structure):    _fields_ = [("model", PicamModel),                ("computer_interface", PicamComputerInterface),                ("sensor_name", pichar * PicamStringSize_SensorName),                ("serial_number", pichar * PicamStringSize_SerialNumber)]似乎第二个参数只是一个字符串,因此您无需对其进行应用pointer()。这是功能的ctypes原型Picam_ConnectDemoCamera():"""Picam_ConnectDemoCamera(PicamModel model, const pichar* serial_number,                        PicamCameraID* id)"""pichar_p = c.c_char_p # assume '\0'-terminated C stringsPicam_ConnectDemoCamera.argtypes = [PicamModel, pichar_p,                                    c.POINTER(PicamCameraID)]Picam_ConnectDemoCamera.restype = c.c_int # assume it returns C int调用它:picam_id = PicamCameraID()rc = Picam_ConnectDemoCamera(2, "serial number here", c.byref(picam_id))print(rc)print(picam_id.sensor_name.value) # C stringprint(picam_id.sensor_name.raw)   # raw memory
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python