【问题标题】:Python ctypes callback function gives "TypeError: invalid result type for callback function"Python ctypes 回调函数给出“TypeError:回调函数的无效结果类型”
【发布时间】:2015-10-08 01:27:38
【问题描述】:

我计划在我的 Python 应用程序中使用由 DLL 导出的 C 函数。这个特定的函数需要多个回调作为参数,所以我在 python 中用 ctypes 定义这样的回调。然而,我很快就陷入了这个简单的测试:

from ctypes import *

someFunction = CFUNCTYPE(POINTER(c_long), c_long)

def someFunctionPy(someLong):
    return pointer(c_long(someLong))


print POINTER(c_long)
print someFunctionPy(1)

someFunctionImpl = someFunction(someFunctionPy)

someFunctionImpl 然后可以作为参数传递给 C 函数。这给了我以下错误:

<class '__main__.LP_c_long'>
<__main__.LP_c_long object at 0x022928F0>
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    someFunctionImpl = someFunction(someFunctionPy)
TypeError: invalid result type for callback function

打印输出告诉我该函数返回了一个正确类型的对象,那么我在这里遗漏了什么?

编辑:当我使用someFunction = CFUNCTYPE(c_void_p, c_long) 时,它似乎确实有效,即使c_void_pPOINTER(c_long) 具有不同的类型。嗯?

但这并没有真正的帮助,因为最终我将不得不使用一个预定义的CFUNCTYPE,它具有POINTER(c_int) 作为返回类型。

【问题讨论】:

  • 使用空指针有什么问题?
  • 正如我所提到的,最终我将不得不使用其他人已定义且我无法编辑的CFUNCTYPECFUNCTYPEPOINTER(c_long) 作为返回类型。
  • 回调使用返回类型的setfunc 在 FFI 结果缓冲区中设置返回值。只有简单类型有setfunc,包括简单指针类型c_char_pc_wchar_pc_void_p。非简单指针类型、数组类型、结构类型没有setfunc,所以不能直接被回调返回。
  • 使用setfunc 不会泄漏非指针类型的内存,但它会泄漏c_char_p 的引用计数和wchar_t * 编码的c_wchar_p 缓冲区。如果将结果类型设置为c_void_p,则可以只返回 ctypes 对象的地址。这使您有责任在 C 库可以访问时保持对象处于活动状态,例如在这种情况下,您需要保留对 c_long 实例的引用。
  • 那为什么在下面的函数定义中使用它:MediaOpenCb = ctypes.CFUNCTYPE(ctypes.POINTER(ctypes.c_int), ctypes.c_void_p, ListPOINTER(ctypes.c_void_p), ctypes.POINTER(ctypes.c_uint64)),它直接来自libvlc API? (我假设已经过测试)

标签: python ctypes ffi


【解决方案1】:

目前这是不可能的。见this CPython bug report

【讨论】:

    猜你喜欢
    • 2016-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    相关资源
    最近更新 更多