在python ctypes.Structure中有结构标记约定吗?

时间:2012-01-19 08:12:58

标签: python struct structure

我正在使用ctypes将visual c ++ 6应用程序移植到python。 它使用相同的Windows库DLL。我只是将Windows窗体移植到python应用程序。

当我在python中将cpp结构发送到dll时,我被困住了。

我试图在结构差异上找到解决方案。从cpp代码,有一个struct tagging(tagTest),但在python代码中没有等价物。那有什么解决方案吗?

这是我要移植的cpp。

======================== cpp part ===================== ===========

BOOL CSMessage(HWND hWnd, const char* string1, const char* string2, const char* ltagTest, int structlen);

typedef struct tagTest
{
    char item1                     [  8];   char _item1;
    char item2                     [  1];   char _item2;
} TcTest, *LPTest;  

void Initiator()
{
    TcTest  ctest   ={0};
    memset(&ctest,0x20,sizeof TcTest);
    move(ctest.item1,"TESTSTRI");
    move(ctest.item2,"1");

    mhandler.CSMessage(GetSafeHwnd(),"String","Call",(char*)&ctest,sizeof TcTest);
}

========================= pythonpart ===================== =======

csMessageProto=ctypes.WINFUNCTYPE(BOOL, HWND, c_char_p, c_char_p, c_char_p, c_int)
csMessageParams=((1,"hWnd",0),(1,"string1",0),(1,"string2",0),(1,"ltagTest",0),(1,"structlen",0))
CSMessage=csMessageProto(("CSMessage",testDll), csMessageParams)

class tagTest(ctypes.Structure):
    _fields_ = [
        ('item1', c_char*8),('_item1', c_char),
        ('item2', c_char*1),('_item2', c_char)
    ]
PtagTest=ctypes.POINTER(tagTest)

utestblock=tagTest()
utestblock.item1=str("TESTSTRI")
utestblock.item2=str(1)

CSMessage(hwnd, "String", "Call", ctypes.byref(utestblock), ctypes.sizeof(utestblock));

修订历史

  1. 添加了cll和python
  2. 的dll函数声明
  3. 使用@avl_sweden建议修改
  4. =====================结果========================= =====

    应用@ avl_sweden的建议后, 经过测试,错误消息是这个。

    ctypes.ArgumentError: argument 4: <type 'exceptions.TypeError'>: wrong type
    

    和类型

    print "Is Type : "+str(ctypes.byref(utestblock))
    
    Is Type : <cparam 'P' (023e5968)>
    

    =============================================== ==========

    因此看起来def和实例中的类型不同。

    在python代码的第一行

    1: csMessageProto=ctypes.WINFUNCTYPE(BOOL, HWND, c_char_p, c_char_p, c_char_p, c_int)
    

    第四个c_char_p不匹配

    16: CSMessage(hwnd, "String", "Call", ctypes.byref(utestblock), ctypes.sizeof(utestblock));
    

    以匹配差异。

    我将代码更改为

    1: csMessageProto=ctypes.WINFUNCTYPE(BOOL, HWND, c_char_p, PtagTest, c_char_p, c_int)
    

    并且代码不返回任何错误。但我找不到它是否通过发送。因为没有从dll返回。

    您认为这是正确的解决方案吗?

    =============================================== ======================================

    我已经过测试,似乎是正确的解决方案。

    再次感谢你。

1 个答案:

答案 0 :(得分:0)

我认为这里有四件事:

首先,您的python结构定义与C代码段中的结构定义不匹配。 python应该是:

class tagTest(ctypes.Structure):
    _fields_ = [
        ('item1', c_char*8), ('_item1',c_char),
        ('item2', c_char*1), ('_item2',c_char)
    ]

我看到的第二件事是你发送一个指向CSMessage函数的指针。

你可以尝试一下:

utestblock=tagTest()
utestblock.item1=str("TESTSTRI")
utestblock.item2=str(1)

loadeddll.CSMessage(hwnd, "String", "Call", ctypes.byref(utestblock),
                    ctypes.sizeof(utestblock))

第三个问题不那么严重,这就是字符串"TESTSTRING"不适合8个字节。

我看到的第四个问题是默认参数的类型是错误的。

请改为尝试:

csMessageParams=((1, "hWnd", 0), (1, "string1", ""), (1, "string2", ""),
                 (1, "ltagTest", ""), (1, "structlen", 0))