python ctype初始化结构

时间:2013-12-27 10:46:08

标签: python windows ctypes

我的结构包含所有unsigned char元素

typedef struct
{
    unsigned char bE;
    unsigned char cH;
    unsigned char cL;
    unsigned char EId1;
    unsigned char EId0;
    unsigned char SId1;
    unsigned char SId0;
    unsigned char DLC;
    unsigned char D0;
    unsigned char D1;
    unsigned char D2;
    unsigned char D3;
    unsigned char D4;
    unsigned char D5;
    unsigned char D6;
    unsigned char D7;
 } CMsg;

以下函数调用结构

extern  int  WriteCMessage(HANDLE hDev,CMsg* pMsg);

我将此结构转换为python ctype

class CMsg(Structure):
   _fields_ = [('bE', c_char),
               ('cH', c_char),
               ('cL', c_char),
               ('EId1', c_char),
               ('EId0', c_char),
               ('SId1', c_char),
               ('SId0', c_char),
               ('DLC', c_char),
               ('D0', c_char),
               ('D1', c_char),
               ('D2', c_char),
               ('D3', c_char),
               ('D4', c_char),
               ('D5', c_char),
               ('D6', c_char),
               ('D7', c_char)]
pmsg = CMsg('\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00')

然后我加载了dll文件

hllDll.WriteCANMessage(handle, pmsg)

但是这会给出错误

  

错误:0x00000000

处的访问冲突

1 个答案:

答案 0 :(得分:3)

您按值传递pmsg,但该函数需要一个指针。由于您已初始化为全零,因此该函数最终取消引用NULL指针。然后,ctypes使用Windows SEH将访问冲突路由到Python异常。

您需要使用byref(pmsg)来传递引用。另外,定义函数argtypes以确保在64位系统上正确处理指针。

from ctypes import *
from ctypes.wintypes import *

class CMsg(Structure):
    _fields_ = [
        ('bE', c_ubyte),
        ('cH', c_ubyte),
        ('cL', c_ubyte),
        ('EId1', c_ubyte),
        ('EId0', c_ubyte),
        ('SId1', c_ubyte),
        ('SId0', c_ubyte),
        ('DLC', c_ubyte),
        ('D0', c_ubyte),
        ('D1', c_ubyte),
        ('D2', c_ubyte),
        ('D3', c_ubyte),
        ('D4', c_ubyte),
        ('D5', c_ubyte),
        ('D6', c_ubyte),
        ('D7', c_ubyte)]

hllDll = cdll...
hllDll.WriteCANMessage.argtypes = [HANDLE, POINTER(CMsg)]

handle = ...
pmsg = CMsg() #  initially memset to {0}
hllDll.WriteCANMessage(handle, byref(pmsg))