我正在尝试使用 Python 的 ctypes 来处理 DLL,但是当我尝试调用作为指向另一个函数的指针传递的函数时,我偶尔会遇到问题。
一点背景...我正在尝试使用Dokan(版本 0.6.0)构建用户空间文件系统。有点松散地说,Dokan 基本上是 Windows 的FUSE。我已经使用 ctypes 包装了 dokan 头文件(类似于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,但它们似乎都不适用于 Windows 64 位上的 Python 2.7。
我的下一个最佳猜测是,这是使用 64 位操作系统的问题。也许用于函数指针的类型不足以正确处理它。在进行了一些谷歌搜索之后,似乎其他人在 Win64 中使用 ctypes 时遇到了问题。我已经为 64 位架构构建了我的 Dokan 库。那我的python代码有问题吗?
任何帮助将不胜感激。我已经为此苦苦挣扎了一段时间。
可以在此处找到类似的帖子。不过,它似乎并不是非常相似。
注意:在 python 代码中,您将看到一些此处未定义的类型(例如 PDOKAN_FILE_INFO)。这些要么是结构,要么是指向结构的指针,为了简洁起见,我没有包括在内。