如何允许将 NoneType 参数或回调函数传递给 ctypes 中的函数
How do I allow NoneType Arguments OR a callback function to be passed to a function in ctypes
我已经开始围绕 C/C++ 库编写一个非常简单的 Python 绑定,出于法律原因我无法在此处共享,因为我没有权限。
它包含一个 WINFUNCTYPE() 作为回调,然后可以用来修饰函数以用作 python 中的回调,并且在我绑定的函数的 argtypes 中定义.
代码如下所示:
from ctypes import *
from ctypes.wintypes import *
dll = WinDLL('path\to\dll')
callback = WINFUNCTYPE(None, POINTER(c_void_p), POINTER(LPBYTE), DWORD, c_ulonglong)
func = dll.FunctionImBinding
func.restype = POINTER(c_void_p)
func.argtypes = [LPCWSTR, callback, c_ulonglong, DWORD, DWORD]
然后我可以像这样使用它
@callback
def callback_func(*args):
#Do something with args
pass
func('string', callback_func, 0, 1, 2)
很好,按预期工作,没有问题。
当我这样做时,问题就来了:
func('string', None, 0, 1, 2)
我收到以下错误:
ctypes.ArgumentError: argument 2: <class 'TypeError'>: expected WinFunctionType instance instead of NoneType
完全清楚为什么。 ctypes 期望看到 WINFUNCTYPE() 作为第二个参数而不是 NoneType,但是在我使用的 SDK 的文档中它指出可以将回调设置为 NULL。但我只是不知道如何修复它,而且我正在努力在网上或在 ctypes 文档中找到任何东西。
这是我第一次尝试绑定 C/C++ 库,如果我忽略了一些明显的东西,请原谅我。如果有人能帮我解决这个问题,我将不胜感激。
好的我在这里找到了解决方案https://ctypes-users.narkive.com/wmJNDPu2/optional-callbacks-passing-null-for-function-pointers
将澄清我在这里所做的事情,而不是删除问题。
定义自定义 from_param 并使用这样的类方法在回调中设置它。
from ctypes import _CFuncPtr
def from_param(cls, obj):
if obj is None:
return None
return _CFuncPtr.from_param(obj)
callback.from_param = classmethod(from_param)
您可以在创建回调时通过传递地址 0 为其提供空函数指针:
func('string', callback(0), 0, 1, 2)
事实上,我查看了 OP 发布的答案中的 link,后来在线程中它具有基本相同的东西......将 None 转换为回调类型,例如cast(None, callback)
.
我已经开始围绕 C/C++ 库编写一个非常简单的 Python 绑定,出于法律原因我无法在此处共享,因为我没有权限。
它包含一个 WINFUNCTYPE() 作为回调,然后可以用来修饰函数以用作 python 中的回调,并且在我绑定的函数的 argtypes 中定义.
代码如下所示:
from ctypes import *
from ctypes.wintypes import *
dll = WinDLL('path\to\dll')
callback = WINFUNCTYPE(None, POINTER(c_void_p), POINTER(LPBYTE), DWORD, c_ulonglong)
func = dll.FunctionImBinding
func.restype = POINTER(c_void_p)
func.argtypes = [LPCWSTR, callback, c_ulonglong, DWORD, DWORD]
然后我可以像这样使用它
@callback
def callback_func(*args):
#Do something with args
pass
func('string', callback_func, 0, 1, 2)
很好,按预期工作,没有问题。
当我这样做时,问题就来了:
func('string', None, 0, 1, 2)
我收到以下错误:
ctypes.ArgumentError: argument 2: <class 'TypeError'>: expected WinFunctionType instance instead of NoneType
完全清楚为什么。 ctypes 期望看到 WINFUNCTYPE() 作为第二个参数而不是 NoneType,但是在我使用的 SDK 的文档中它指出可以将回调设置为 NULL。但我只是不知道如何修复它,而且我正在努力在网上或在 ctypes 文档中找到任何东西。
这是我第一次尝试绑定 C/C++ 库,如果我忽略了一些明显的东西,请原谅我。如果有人能帮我解决这个问题,我将不胜感激。
好的我在这里找到了解决方案https://ctypes-users.narkive.com/wmJNDPu2/optional-callbacks-passing-null-for-function-pointers
将澄清我在这里所做的事情,而不是删除问题。
定义自定义 from_param 并使用这样的类方法在回调中设置它。
from ctypes import _CFuncPtr
def from_param(cls, obj):
if obj is None:
return None
return _CFuncPtr.from_param(obj)
callback.from_param = classmethod(from_param)
您可以在创建回调时通过传递地址 0 为其提供空函数指针:
func('string', callback(0), 0, 1, 2)
事实上,我查看了 OP 发布的答案中的 link,后来在线程中它具有基本相同的东西......将 None 转换为回调类型,例如cast(None, callback)
.