简体   繁体   中英

Python Ctypes passing pointer to structure containing void pointer array

Explanation:

I am attempting to access a function in a DLL using python 2.7 on Windows 7 that requests a pointer to a structure containing a void pointer array. At the moment, I do not have the source code for this DLL, but I do have the header file which contains the function prototype for the function in question as well as the definitions of the structures.

The Structures:

    typedef struct {
        unsigned long      PagesPerMark[MAX_NUM_DMA_CHANNELS];
        void               *VirtDMAAdr[MAX_NUM_DMA_CHANNELS][MAX_DMA_PAGES_PER_CH];
        unsigned long long PhysDMAAdr[MAX_NUM_DMA_CHANNELS][MAX_DMA_PAGES_PER_CH];
    } s_DMAConfig;

    typedef struct {
        s_DMAConfig DMA;
        void        *User;
    } s_Adapter;

The Function Prototype:

    #ifdef WIN32
    #define EXPORTULONG __declspec(dllexport) unsigned long
    #else
    #define EXPORTULONG unsigned long
    #endif  
    EXPORTULONG Adapter_Zero(s_Adapter *p_Adapter);

My attempt at accessing the function using Python:

    import ctypes

    MAX_NUM_DMA_CHANNELS = 4
    MAX_DMA_PAGES_PER_CH = 1024

    class s_DMAConfig(ctypes.Structure):
        _fields_ = [("PagesPerMark", ctypes.c_ulong * MAX_NUM_DMA_CHANNELS),
                   ("VirtDMAAddr", ctypes.POINTER(ctypes.c_void_p * MAX_NUM_DMA_CHANNELS * MAX_DMA_PAGES_PER_CH)),
                   ("PhysDMAAdr", ctypes.c_ulonglong * MAX_NUM_DMA_CHANNELS * MAX_DMA_PAGES_PER_CH)]

    class s_Adapter(ctypes.Structure):
        _fields_ = [("DMA", s_DMAConfig),
                   ("User", ctypes.c_void_p)]

    uLongArray = ctypes.c_ulong * MAX_NUM_DMA_CHANNELS
    pagePerMark = uLongArray()
    voidPtrArr = ctypes.c_void_p * MAX_NUM_DMA_CHANNELS * MAX_DMA_PAGES_PER_CH
    virtDMAAddr = voidPtrArr()
    uLongLongArray = ctypes.c_ulonglong * MAX_NUM_DMA_CHANNELS * MAX_DMA_PAGES_PER_CH
    physDMAAddr = uLongLongArray()
    dmaConfig = s_DMAConfig(pagePerMark, ctypes.pointer(voidPtrArr()), physDMAAddr)

    userInput = ctypes.c_void_p()
    adapter = s_Adapter(dmaConfig, userInput)

    ## Load DLL
    RRadapter = ctypes.cdll.LoadLibrary("myLib.dll")
    Adapter_Zero = RRadapter.Adapter_Zero
    Adapter_Zero.restype = ctypes.c_ulong   
    Adapter_Zero.argtypes = [ctypes.POINTER(s_Adapter),]
    Adapter_Zero(ctypes.byref(adapter))

When I attempt to run this solution it crashes the python interpreter right after the DLL function call is made. There are no return errors, so I'm not sure what course of action I should take next. I'm pretty new to Python, so any advice would be greatly appreciated.

I've looked at other somewhat similar questions such as Python ctypes pointer to pointer to structure as well as Python & Ctypes: Passing a struct to a function as a pointer to get back data but to no avail. Additionally, I could not find any good examples of using a void ptr array, so I hope this question will aid others who may be in a similar situation.

My questions for you:

1) Did I correctly implement the call to the DLL using Python's ctypes?

2) In the case that I did correctly implement the Python script (most likely I didn't,) what free tools could I use to investigate the reason for the failure?

Have you any crash reports?

Have you tried:

RRadapter = ctypes.CDLL('lib.dll')

This worked well for my last project.

Sorry no right to comment yet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM