Python `ctypes` - How to copy buffer returned by C function into a bytearray

soumik

A pointer to buffer of type POINTER(c_ubyte) is returned by the C function (the image_data variable in the following code). I want this data to be managed by Python, so I want to copy it into a bytearray. Here's the function call

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

We get to know the width and height of the image only after that call, so can't pre-allocate a bytearray.

I would have used

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

 image_data_bytearray = bytearray(cast(image_data, array_type))

But the type to cast to must be a pointer, not array, so I get an error.

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

What should I do?

soumik

OK, reading the answer to the question linked to in the comments (thanks, @"John Zwinck" and @"eryksun"), there are two ways of storing the data, either in a bytearray or a numpy.array. In all these snippets, image_data is of type POINTER(c_ubyte), and we have array_type defined as -

array_type = c_ubyte * num_channels * width * height

We can create a bytearray first and then loop over and set the bytes

arr_bytes = bytearray(array_size)
for i in range(array_size):
    arr_bytes[i] = image_data[i]

Or a better way is to create a C array instance using from_address and then initialize a bytearray with it -

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

# Copy into bytearray
image_data_bytearray = bytearray(image_data_carray)

And during writing the image (didn't ask this question, just sharing for completeness), we can obtain pointer to the bytearray data like this and give it to stbi_write_png

image_data_carray = array_type.from_buffer(image_data_bytearray)
image_data = cast(image_data_carray, POINTER(c_ubyte))

The numpy based way of doing it is as answered in the linked question

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

This alone however only points to the memory returned by the C function, doesn't copy into a Python-managed array object. We can copy by creating a numpy array as

image_data = np.array(image_data_ptr)

To confirm I have done an assert all(arr_np == arr_bytes) there. And arr_np.dtype is uint8.

And during writing the image, we can obtain a pointer to the numpy array's data like this

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

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

ctypes: How to access array of structure returned by function?

From Dev

python ctypes how to write string to given buffer

From Dev

python: Convert bytearray to ctypes Struct

From Dev

ctypes from buffer - Python

From Dev

How to copy a bytearray

From Dev

Callbacks with ctypes (How to call a python function from C)

From Dev

How to pass a python list to C function (dll) using ctypes

From Dev

How to overload weak declared function of a C library using ctypes in python?

From Dev

How to pass python 2d matrix to C function ctypes

From Dev

How do I access values stored in an array inside a C struct returned to Python via ctypes?

From Dev

Python 3 ctypes call for function with returned struct fails with segfault

From Dev

unexpected integer returned from a C function by calling it using ctypes

From Dev

Python Ctypes: Convert returned C array to python list, WITHOUT numpy

From Dev

Python ctypes: how to define a callback having a buffer pointer and a length in argument?

From Dev

Have C library call python function with ctypes

From Dev

Python ctypes: calling a function with custom types in c

From Dev

Ctypes - How to parser buffer content?

From Dev

ctypes.Structure.from_buffer_copy doesn't check \0 for c_char-type

From Dev

How use the returned "buffer" of Electronjs function "getNativeWindowHandle()" in native functions?

From Dev

How to pass lists into a ctypes function on python

From Dev

In Python how to reference the value of a function string parameter when converting to ctypes c_wchar_p

From Dev

Python 3 ctypes call to a function that needs an indirect reference to a buffer through another structure

From Dev

Python ctypes function returns ValueError when C function returns NULL

From Dev

Python - bytearray function with string literal

From Dev

Write buffer in C which is allocated in python using ctypes, and read back again in python

From Dev

Casting a bytearray instance in ctypes

From Dev

Python ctypes passing string pointer / buffer

From Dev

Returning a C array from a C function to Python using ctypes

From Dev

Using Rust returned array in Python using ctypes

Related Related

  1. 1

    ctypes: How to access array of structure returned by function?

  2. 2

    python ctypes how to write string to given buffer

  3. 3

    python: Convert bytearray to ctypes Struct

  4. 4

    ctypes from buffer - Python

  5. 5

    How to copy a bytearray

  6. 6

    Callbacks with ctypes (How to call a python function from C)

  7. 7

    How to pass a python list to C function (dll) using ctypes

  8. 8

    How to overload weak declared function of a C library using ctypes in python?

  9. 9

    How to pass python 2d matrix to C function ctypes

  10. 10

    How do I access values stored in an array inside a C struct returned to Python via ctypes?

  11. 11

    Python 3 ctypes call for function with returned struct fails with segfault

  12. 12

    unexpected integer returned from a C function by calling it using ctypes

  13. 13

    Python Ctypes: Convert returned C array to python list, WITHOUT numpy

  14. 14

    Python ctypes: how to define a callback having a buffer pointer and a length in argument?

  15. 15

    Have C library call python function with ctypes

  16. 16

    Python ctypes: calling a function with custom types in c

  17. 17

    Ctypes - How to parser buffer content?

  18. 18

    ctypes.Structure.from_buffer_copy doesn't check \0 for c_char-type

  19. 19

    How use the returned "buffer" of Electronjs function "getNativeWindowHandle()" in native functions?

  20. 20

    How to pass lists into a ctypes function on python

  21. 21

    In Python how to reference the value of a function string parameter when converting to ctypes c_wchar_p

  22. 22

    Python 3 ctypes call to a function that needs an indirect reference to a buffer through another structure

  23. 23

    Python ctypes function returns ValueError when C function returns NULL

  24. 24

    Python - bytearray function with string literal

  25. 25

    Write buffer in C which is allocated in python using ctypes, and read back again in python

  26. 26

    Casting a bytearray instance in ctypes

  27. 27

    Python ctypes passing string pointer / buffer

  28. 28

    Returning a C array from a C function to Python using ctypes

  29. 29

    Using Rust returned array in Python using ctypes

HotTag

Archive