Вызов WinDLL в Python со сложной структурой не работает - PullRequest
0 голосов
/ 10 октября 2019

Я пытаюсь вызвать WinDll из Python, который обычно работает хорошо для простых функций. Моя проблема в том, что мне нужно передать указатель на сложную структуру, которая не работает. Я не могу определить аргументы функции WinDll.

Объявление функции в c и типы данных выглядят следующим образом:

typedef struct VBLFileStatistics_t
{
    DWORD     mStatisticsSize;                   /* sizeof (VBLFileStatistics) */
    BYTE      mApplicationID;                    /* application ID */
    BYTE      mApplicationMajor;                 /* application major number */
    BYTE      mApplicationMinor;                 /* application minor number */
    BYTE      mApplicationBuild;                 /* application build number */
    ULONGLONG mFileSize;                         /* file size in bytes */
    ULONGLONG mUncompressedFileSize;             /* uncompressed file size in bytes */
    DWORD     mObjectCount;                      /* number of objects */
    DWORD     mObjectsRead;                      /* number of objects read */
} VBLFileStatistics;

( BOOL)   BLGetFileStatistics( HANDLE hFile, VBLFileStatistics* pStatistics);

Загрузка и получение дескриптора работает нормально.

import sys
import ctypes 
from ctypes import wintypes

GENERIC_READ         = wintypes.DWORD(0x80000000) 
INVALID_HANDLE_VALUE = -1 

class VBLFileStatistics(ctypes.Structure):
        _fields_ = [
        ("mStatisticsSize", wintypes.DWORD),
        ("mApplicationID", wintypes.BYTE),
        ("mApplicationMajor", wintypes.BYTE),
        ("mApplicationMinor", wintypes.BYTE),
        ("mApplicationBuild", wintypes.BYTE),
        ("mFileSize", ctypes.c_ulonglong),
        ("mUncompressedFileSize", ctypes.c_ulonglong),
        ("mObjectCount", wintypes.DWORD),
        ("mObjectsRead", wintypes.DWORD)]

lib = ctypes.WinDLL('myDll.dll')

#( HANDLE) BLCreateFile( LPCSTR lpFileName, DWORD dwDesiredAccess);
lib.BLCreateFile.restype  = wintypes.HANDLE
lib.BLCreateFile.argtypes = [wintypes.LPCSTR, wintypes.DWORD]

handle = lib.BLCreateFile(b'test.blf',GENERIC_READ)
    if(ctypes.c_int(handle).value == INVALID_HANDLE_VALUE):
        print("Error occured reading the file!!!")
        sys.exit()

#( BOOL)   BLGetFileStatistics( HANDLE hFile, VBLFileStatistics* pStatistics);
lib.BLGetFileStatistics.restype  = wintypes.BOOL
lib.BLGetFileStatistics.argtypes = [wintypes.HANDLE, ctypes.pointer(VBLFileStatistics)]

stats_obj = VBLFileStatistics()
success = lib.BLGetFileStatistics(handle, ctypes.pointer(stats_obj))

Я получаю следующее сообщение об ошибке:

Traceback (most recent call last):
  File "parser.py", line 104, in <module>
    lib.BLGetFileStatistics.argtypes = [wintypes.HANDLE, ctypes.pointer(VBLFileStatistics)]
TypeError: _type_ must have storage info

Я также попытался установить argtypes для пустого указателя (wintypes.LPCVOID) и затем передать указатель на stats_objдля BLGetFileStatistics, которая не вызвала ошибку, но также не работала, так как stats_obj был еще пуст после вызова.

...