2

uint8_t *begin();割り当てられたメモリへのポインタを返すC 関数があります。

ここにctypesバインディングがあります:

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

メモリを整数の配列で埋める必要があります。これの代わりにそれを行うより速い方法はありますか?

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

反復可能なデータには多くの項目、数百万の整数などを含めることができるため、配列全体を反復することは非常に高速な方法であるとは思えません。

4

2 に答える 2

2

依存関係を追加できる場合、numpyを使用するとこれが簡単になります。

これが私がまとめた例です。

C (長さが 10 に設定されていることに注意してください)

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

そしてパイソン

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

numpy に精通している場合は、この方法でも多次元配列を作成できます。

誰がメモリを所有しているのか、また、基礎となる C に近づいているため、どこでも segfault (またはリーク) しないようにメモリをクリアする方法について少し考える必要があります。たとえばdel buffer、作成されたバッファは解放されません。 C.

于 2012-05-30T20:08:41.247 に答える
1

Python リストには対応するC 型があり、これにはPyObjectの内部 C 配列があると思います。intしたがって、とにかくリスト項目を に変換するには、リスト項目を反復処理する必要があります。1行で書くにはコツがいるかもしれませんが、シンプルな方がいいと思います。

PS配列モジュールの使用を検討してください:

>>> 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
于 2012-05-24T05:15:19.960 に答える