2

I have a C function uint8_t *begin(); which returns a pointer to allocated memory.

Here is a ctypes binding to it:

begin = mylibrary.begin
begin.argtypes = ()
begin.restype = ctypes.POINTER(ctypes.c_uint8)

I need to fill memory with an array of the integers. Is there any quicker way to do it instead of this?

buffer = begin()
data = range(10)
for idx, value in enumerate(data):
    buffer[idx] = ctypes.c_uint8(value)

It doesn't look to me, that iterating over the whole array is a very fast method, because that iterable data can contains a lot of items, millions of integers or something like this.

2 Answers 2

3

If you can add dependencies, numpy makes this easier.

Here is an example I put together.

The C (note the length is set to 10)

#include <stdlib.h>
int *begin(void) {
    return calloc(10, sizeof(int));
}

and the python

import numpy as np
import ctypes
# make the data I want to put into C
data = np.arange(10, dtype=ctypes.c_int)
# setup the ctypes just as you did
mylibrary = ctypes.CDLL('a.out')
begin = mylibrary.begin
begin.argtypes = ()
begin.restype = ctypes.POINTER(ctypes.c_int)
# and do the same memmove that Kirill suggested
ctypes.memmove(buffer, data.ctypes.get_data(), ctypes.sizeof(ctypes.c_int)*len(data))
# and print some out
print buffer[2]
# 2

If you are clever with numpy you can do multidimensional arrays this way too.

One needs to think a bit on who owns the memory and how to clear it out and not segfault (or leak) anywhere as you are getting close the the underlying C. For example del buffer will not free the created buffer, that has to be done in C.

Sign up to request clarification or add additional context in comments.

Comments

2

Python list has corresponding C type which I guess has internal C array of PyObject's. Consequently, you have to iterate over list items in order to convert them to int's anyway. There is may be some trick way to write it in one line but I think the simpler the better.

P.S. Consider using array module:

>>> import ctypes
>>> from array import array
>>> TenInts = ctypes.c_int * 10
>>> arr = array('i', range(10))
>>> carr = TenInts()
>>> arr_addr, arr_len = arr.buffer_info()[0], len(arr) * arr.itemsize
>>> ctypes.memmove(carr, arr_addr, arr_len)
13893440
>>> print '; '.join(map(str, carr))
0; 1; 2; 3; 4; 5; 6; 7; 8; 9

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.