Я пытаюсь использовать ctypes Python для работы с DLL, но иногда я сталкиваюсь с проблемой, когда пытаюсь вызвать функцию, которая передается как указатель на другую функцию.
Немного предыстории ... Я пытаюсь создать файловую систему пространства пользователя, используя Dokan (версия 0.6.0). В некотором смысле, Dokan в основном FUSE для Windows. Я обернул заголовочный файл dokan с помощью ctypes (аналогично pydokan ). Этот заголовочный файл содержит определение указателя на функцию, которое выглядит следующим образом
typedef int (WINAPI *PFillFindData) (PWIN32_FIND_DATAW, PDOKAN_FILE_INFO);
Он также содержит прототип другой функции
int (DOKAN_CALLBACK *FindFilesWithPattern) (
LPCWSTR,
LPCWSTR,
PFillFindData,
PDOKAN_FILE_INFO);
Соответствующие определения ctypes выглядят следующим образом
PFillFindData = ctypes.WINFUNCTYPE(ctypes.c_int,
PWIN32_FIND_DATAW,
PDOKAN_FILE_INFO)
FindFilesWithPattern = ctypes.WINFUNCTYPE(ctypes.c_int,
ctypes.c_wchar_p,
ctypes.c_wchar_p,
PFillFindData,
PDOKAN_FILE_INFO)
Реализация этой последней функции (FindFilesWithPattern) должна вызывать функцию FillFindData, которую она передает. Базовая реализация выглядит следующим образом
def FindFilesWithPattern(self,
FileName,
SearchPattern,
FillFindData,
DokanFileInfo):
if FileName == '\\':
File = WIN32_FIND_DATAW(FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_READONLY,
FILETIME(1, 1),
FILETIME(1, 1),
FILETIME(1, 1),
0,
len(self.HelloWorldText),
0,
0,
'Hello_World.txt',
'Hello_~1.txt')
pFile = PWIN32_FIND_DATAW(File)
FillFindData(pFile, DokanFileInfo)
return 0
else:
return -ERROR_FILE_NOT_FOUND
Когда вызывается эта функция, я иногда получает следующую ошибку:
Traceback (most recent call last):
File "_ctypes/callbacks.c", line 313, in 'calling callback function'
File "src/test.py", line 385, in FindFilesWithPattern
FillFindData(pFile, DokanFileInfo)
WindowsError: exception: access violation reading 0x0000000000000008
Я недоволен. На первый взгляд это выглядит так, будто я пытаюсь получить доступ к памяти, находящейся вне диапазона. Но эта ошибка возникает только изредка. Иногда все работает нормально, и результаты возвращаются, как и ожидалось. (Чтобы уточнить, когда я говорю время от времени, я имею в виду, что ошибка возникает при некоторых запусках программы, а не при других. Ошибка, по-видимому, возникает или не возникает последовательно в течение одного запуска.)
Тогда мне стало интересно, получаю ли я обратно код ошибки, а не адрес памяти. Я обнаружил здесь , что , если это код ошибки, то это может означать «недостаточно памяти». Когда я смотрю на системный монитор, это не кажется проблемой, хотя. Я пытался запустить различные профилировщики памяти, такие как Heapy и Meliae , но ни один из них, похоже, не работает с Python 2.7 в 64-битной Windows.
Следующим моим лучшим предположением было то, что это проблема с использованием 64-битной ОС. Возможно, тип, используемый для указателя функции, недостаточен для правильного обращения к нему. После некоторого поиска в Google, кажется, у других возникли проблемы с использованием ctypes в Win64. Я построил свою библиотеку Dokan для 64-битной архитектуры. Есть ли проблема с моим кодом Python?
Любая помощь будет принята с благодарностью. Я боролся с этим в течение некоторого времени.
Подобный пост можно найти здесь . Хотя это не кажется ужасно аналогичным.
Примечание. В коде Python вы увидите некоторые типы, которые здесь не определены (например, PDOKAN_FILE_INFO). Это либо структуры, либо указатели на структуры, которые я для краткости не включил.