web-dev-qa-db-ja.com

ctypesを使用してPythonリストをC配列に変換するにはどうすればよいですか?

次の2セットのコードがある場合、それらをどのように接着するのですか?

void
c_function(void *ptr) {
    int i;

    for (i = 0; i < 10; i++) {
        printf("%p", ptr[i]);
    }

    return;
}


def python_routine(y):
    x = []
    for e in y:
        x.append(e)

Xの要素の連続したリストでc_functionを呼び出すにはどうすればよいですか? xをc_void_pにキャストしようとしましたが、うまくいきませんでした。

私も次のようなものを使用しようとしました

x = c_void_p * 10 
for e in y:
    x[i] = e

しかし、これは構文エラーになります。

Cコードは明らかに配列のアドレスを必要とします。どうすればこれを実現できますか?

39

次のコードは任意のリストで機能します。

import ctypes
pyarr = [1, 2, 3, 4]
arr = (ctypes.c_int * len(pyarr))(*pyarr)
74
Gabi Purcaru

ctypesチュートリアル から:

>>> IntArray5 = c_int * 5
>>> ia = IntArray5(5, 1, 7, 33, 99)
8
Ryan Ginstrom

これは受け入れられた答えの説明です。

ctypes.c_int * len(pyarr)は、長さ4のc_int型の配列(シーケンス)を作成します( pythonpython 2 )。 c_intはコンストラクターが1つの引数を取るオブジェクトであるため、(ctypes.c_int * len(pyarr)(*pyarr)pyarrからの各c_intインスタンスのワンショット初期化を行います。 読みやすい 形式は次のとおりです。

pyarr = [1, 2, 3, 4]
seq = ctypes.c_int * len(pyarr)
arr = seq(*pyarr)

type関数とseqの違いを確認するには、arr関数を使用します。

7
akhan
import ctypes
import typing

def foo(aqs : typing.List[int]) -> ctypes.Array:
    array_type = ctypes.c_int64 * len(aqs)
    ans = array_type(*aqs)
    return ans

for el in foo([1,2,3]):
    print(el)

これにより以下が得られます。

1
2
3
1
Jörg Beyer