Python ctypes:使用函数指针

我正在尝试使用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位OS的问题。可能用于函数指针的类型不足以正确解决它。经过一番谷歌搜索之后,似乎其他人在Win64中使用ctypes时遇到了问题。我已经为64位体系结构构建了Dokan库。那我的python代码有问题吗? 任何帮助将不胜感激。我已经为此苦了一段时间了。 在这里可以找到类似的帖子。不过,这似乎并不十分相似。 注意:在python代码中,您会看到一些此处未定义的类型(例如PDOKAN_FILE_INFO)。为了简洁起见,这些不是结构而是指向结构的指针。     
已邀请:
        您如何实例化和使用回调?回调必须在其可以调用的生存期内保持作用域。看到这个答案。这些 编辑 澄清我认为问题是... 我看到您必须实现一个实现类似于
FindFilesWithPattern
的回调的
DOKAN_OPERATIONS
结构,然后使用该结构调用
DokanMain
来挂载文件系统。填写结构时,您应该为回调创建一个类型,然后使用Python函数实例化该回调。类似于(伪代码):
#Create the callback pointer type
PFINDFILESWITHPATTERN = ctypes.WINFUNCTYPE(ctypes.c_int,
                                          ctypes.c_wchar_p,
                                          ctypes.c_wchar_p,
                                          PFillFindData,
                                          PDOKAN_FILE_INFO) 

# Implement in Python
def FindFilesWithPatternImpl(...):
    # implementation

# Create a callback pointer object
FindFilesWithPattern = PFINDFILESIWTHPATTERN(FindFilesWithPatternImpl)

# Create the required structure listing the callback
dokan_op = DOKAN_OPERATIONS(...,FindFilesWithPattern,...)

# Register the callbacks
DokanMain(byref(dokan_op))
在可以使用回调的有效期内,必须保留对对象“ 9”的引用。如果执行类似于以下的安装Dokan:
def mount():
    # Create structure locally
    dokan_op = DOKAN_OPERATIONS(...)
    # Spin off thread to mount Dokan
    threading.Thread(DokanMain,args=(byref(dokan_op),))

mount()
一旦
mount()
返回,
dokan_op
将被销毁。这是我的原始答案描述的情况,可能会导致您看到错误。我正在理论化您的问题,因为我不知道其余的代码是什么样子,但是我认为您在Python中实现
FindFilesWithPattern
的方式是正确的,尤其是。因为您说它间歇性地工作。我以前遇到过失败,上述情况或类似情况会导致您看到错误。 希望这可以帮助...     

要回复问题请先登录注册