есть ли соглашения о тегах структуры в python ctypes.Structure? - PullRequest
0 голосов
/ 19 января 2012

Я портирую приложение Visual C ++ 6 на Python, используя ctypes.Он использует ту же библиотеку Windows библиотеки DLL.и я только портирую формы Windows на приложение Python.

, и я застреваю, когда отправляю структуру cpp в dll на python.

Я попытался найти решение по различиям в структуре.из кода cpp есть структурная пометка (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. добавлено объявление функции dll для cpp и python
  2. пересмотрено с предложениями @avl_sweden

===================== результат ==============================

после применения предложения @ avl_sweden. После теста появляется сообщение об ошибке:

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

и для типа

print "Is Type : "+str(ctypes.byref(utestblock))

Is Type : <cparam 'P' (023e5968)>

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

, поэтому похоже, что типы различаются в def и instance.

в первой строке кода 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 голосов
/ 20 января 2012

Я вижу четыре неправильные вещи:

Во-первых, ваше определение структуры 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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...