Using Python Ctypes to pass struct pointer to a DLL function

后端 未结 2 826
慢半拍i
慢半拍i 2020-12-19 18:10

I am attempting to access a function in a DLL file using Python ctypes. The provided function description is below.



        
相关标签:
2条回答
  • 2020-12-19 18:30

    Likely, you're not entering the exact structure fields in the exact same order. If you don't, then you usually get random data or segfaults. To access a library with ctypes, you usually need to look inside the header (.h file) to copy the exact structure definition. Alternatively, use cffi with ffi.verify() if you don't want to depend on the precise layout.

    0 讨论(0)
  • 2020-12-19 18:32

    Your definition of PicamCameraID structure is incorrect: sensor_name and serial_number are arrays:

    """
    struct PicamCameraID {
      PicamModel             model;
      PicamComputerInterface computer_interface;
      pichar                 sensor_name[PicamStringSize_SensorName];
      pichar                 serial_number[PicamStringSize_SerialNumber]; 
    };
    """
    import ctypes as c
    
    PicamStringSize_SensorName = PicamStringSize_SerialNumber = 64
    PicamModel = PicamComputerInterface = c.c_int
    pichar = c.c_char
    
    class PicamCameraID(c.Structure):
        _fields_ = [("model", PicamModel),
                    ("computer_interface", PicamComputerInterface),
                    ("sensor_name", pichar * PicamStringSize_SensorName),
                    ("serial_number", pichar * PicamStringSize_SerialNumber)]
    

    It seems the second argument is just a string, so you don't need to apply pointer() to it. Here's the ctypes prototype for Picam_ConnectDemoCamera() function:

    """
    Picam_ConnectDemoCamera(PicamModel model, const pichar* serial_number,
                            PicamCameraID* id)
    """
    pichar_p = c.c_char_p # assume '\0'-terminated C strings
    Picam_ConnectDemoCamera.argtypes = [PicamModel, pichar_p,
                                        c.POINTER(PicamCameraID)]
    Picam_ConnectDemoCamera.restype = c.c_int # assume it returns C int
    

    To call it:

    picam_id = PicamCameraID()
    rc = Picam_ConnectDemoCamera(2, "serial number here", c.byref(picam_id))
    print(rc)
    print(picam_id.sensor_name.value) # C string
    print(picam_id.sensor_name.raw)   # raw memory
    
    0 讨论(0)
提交回复
热议问题