【问题标题】:C function passes a pointer and a length, and a Python callback needs to make an array and assign itC函数传递一个指针和一个长度,Python回调需要做一个数组并赋值
【发布时间】:2011-03-07 20:19:07
【问题描述】:

我正在包装一个使用回调作为外部内存分配器的 C 库。基本上,它不是自己做 malloc 和 free ,而是公开几个回调来制作指定大小的缓冲区。将它们与 ctypes 连接起来相当容易,而且所有这些似乎都在工作。但是,我似乎无法将数组连接到传入的指针。

C 接口看起来像这样:

extern int (*alloc_int_buffer_callback)(some_struct* buffer, uint32_t length);

我已经通过 ctypes 定义了结构,并且它似乎完美匹配。

ctypes 回调看起来像这样:

_int_functype = CFUNCTYPE(c_int, POINTER(some_struct), c_uint)

我遇到的问题是试图让 POINTER(some_struct) 实例指向一个类型为 (c_int * length) 的数组似乎不起作用。这是我现在收到的回调:

def _alloc_struct_buffer(ptr, length):
    arr_type = SomeStruct * length
    arr = arr_type()

    ptr.contents = cast(addressof(arr), POINTER(SomeStruct))

    return 1

不幸的是,我收到了一条错误消息,类似于“预期 SomeStruct 而不是 LP_SomeStruct”。我错过了什么?

【问题讨论】:

  • 您的 C 原型的返回类型为 int*,而您的 ctypes 原型的返回类型为 int。哪个是对的?
  • 哎呀,我打错了。谢谢你的收获。

标签: python ctypes


【解决方案1】:

如果要在参数中返回指针,则需要传入指向指针的指针:

extern int alloc_int_buffer_callback(some_struct **buffer, uint32_t length);

如果你只是传入一个指针,在函数内部改变指针不会有任何作用,因为你是按值传递指针的。

在你的 Python 回调中,你可以使用

ptr.contents = cast(arr, POINTER(SomeStruct))

更改原型后。

【讨论】:

  • 不幸的是,当 C 代码尝试访问内存时,我现在遇到了段错误。
  • @Lee:您需要在一些更持久的 Python 数据结构中存储对 arr 的引用。如果只在回调中本地创建,会立即被垃圾回收。
  • 我不敢相信我错过了。有时我想知道我是如何养活自己的。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-26
  • 2017-07-23
相关资源
最近更新 更多