gpt4 book ai didi

Python `ctypes` - 如何将 C 函数返回的缓冲区复制到字节数组中

转载 作者:行者123 更新时间:2023-12-01 02:54:34 27 4
gpt4 key购买 nike

C 函数返回指向 POINTER(c_ubyte) 类型缓冲区的指针(以下代码中的 image_data 变量)。我希望这些数据由 Python 管理,因此我想将其复制到 bytearray 中。这是函数调用

image_data = stb_image.stbi_load(filename_cstr, byref(width),
byref(height), byref(num_channels),
c_int(expected_num_channels))

只有在调用之后我们才能知道图像的宽度高度,因此无法预先分配bytearray

我会用

 array_type = c.c_ubyte * (num_channels.value * width.value * height.value)

image_data_bytearray = bytearray(cast(image_data, array_type))

但是要转换的类型必须是指针,而不是数组,所以我收到错误。

TypeError: cast() argument 2 must be a pointer type, not c_ubyte_Array_262144

我应该做什么?

最佳答案

好的,阅读评论中链接的问题的答案(感谢@“John Zwinck”和@“eryksun”),有两种存储数据的方法,或者在 bytearray 中> 或 numpy.array。在所有这些片段中,image_data 的类型为 POINTER(c_ubyte),并且我们将 array_type 定义为 -

array_type = c_ubyte * num_channels * width * height

我们可以先创建一个字节数组,然后循环并设置字节

arr_bytes = bytearray(array_size)
for i in range(array_size):
arr_bytes[i] = image_data[i]
<小时/>

或者更好的方法是使用 from_address 创建一个 C 数组实例,然后用它初始化一个 bytearray -

image_data_carray = array_type.from_address(addressof(image_data.contents))

# Copy into bytearray
image_data_bytearray = bytearray(image_data_carray)

在写入图像的过程中(没有问这个问题,只是为了完整性而共享),我们可以像这样获取指向字节数组数据的指针并将其交给stbi_write_png

image_data_carray = array_type.from_buffer(image_data_bytearray)
image_data = cast(image_data_carray, POINTER(c_ubyte))
<小时/>

基于 numpy 的方法如链接问题中的答案

address = addressof(image_data.contents)
image_data_ptr = np.ctypeslib.as_array(array_type.from_address(address))

然而,这仅指向 C 函数返回的内存,不会复制到 Python 管理的数组对象中。我们可以通过创建一个 numpy 数组来复制

image_data = np.array(image_data_ptr)

为了确认我已经在那里做了assert all(arr_np == arr_bytes)。并且arr_np.dtypeuint8

在写入图像的过程中,我们可以获得一个指向 numpy 数组数据的指针,如下所示

image_data = image_data_numpy.ctypes.data_as(POINTER(c_ubyte))

关于Python `ctypes` - 如何将 C 函数返回的缓冲区复制到字节数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44353540/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com