Я пытаюсь вызвать 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
был еще пуст после вызова.