6

いくつかのハッキングで、python c-types を使用して Python と C の間でデータをやり取りしました。少し面倒に思えるので、経験豊富な誰かが私が何か間違ったことをしているのか、それとも必要以上に難しくしているのかを教えてくれることを望んでいました.

Python コード:

from ctypes import cdll, POINTER, byref, c_double
lib = cdll.LoadLibrary('./test.so')

def alloc_arrays(length, python_list):
    # Create array of float*
    data = ((POINTER(c_double)) * length)()
    out_data = ((POINTER(c_double)) * length)()
    for i in xrange(length):
        # Create arrays of float
        data[i] = (c_double * 3)()
        out_data[i] = (c_double * 3)()
        # Set Values
        for j in xrange(3):
            data[i][j] = python_list[i][j]
            out_data[i][j] = 0.0
    return data, out_data

if __name__ == "__main__":
    a = [[1.0, 11.0, 21.0],
         [2.0, 12.0, 22.0],
         [3.0, 13.0, 23.0],
         [4.0, 14.0, 24.0],
         [5.0, 15.0, 25.0],
         [6.0, 16.0, 26.0],
         [7.0, 17.0, 27.0]]
    in_data, out_data = alloc_arrays(len(a), a)
    out_len = lib.smain(byref(in_data), len(a), out_data)

    print "out_len", out_len
    clean_out = [None, None, None]
    clean_out = [clean_out[:] for i in xrange(out_len)]
    for i in xrange(out_len):
        for j in xrange(3):
            clean_out[i][j] = out_data[i][j]
    print "Out:", clean_out

C コード (test.c):

int smain(double* in_points[3], int in_len, double* out_points[3]){
    int i;
    int j;
    printf("%s", "\n");
    for(i = 0; i < in_len; i++){
        for(j = 0; j < 3; j++){
            printf("%g, ", *in_points[i][j]);
        }
        printf("%s", "\n");
    }
    printf("%s", "\n");

    //*out_points = malloc(len*sizeof(float[3]));
    int out_len = in_len-2; //Randomly chosen shorter length
    for(i = 0; i < out_len; i++){
        for(j = 0; j < 3; j++){
            //Random function just to see I can do this
            *out_points[i][j] = i*j;
        }
    }
    return out_len;
}

ビルドするには、次を使用します。

gcc -c -fPIC test.c
gcc -shared -o test.so test.o

私が疑問に思っている主なことは、C に渡す空の 2D ベクトルを作成するより良い方法があるかどうか、および ctypes との間で変数を Python 型にキャストするより良い方法があるかどうかです。alloc_arrays 関数が変換を行わなければならないのは好きではありません。また、for ループで c_types 2D リストを読み取るのも好きではありません (少し面倒なことをしたことに気づきました)。

編集:このコードが期待どおりに機能することを明確にしたいだけです。改善する方法がいくつかあると思います。

4

1 に答える 1

0

これはあなたの正確なコードと ctypes に関する答えではありませんが、貢献したかったのです...

最近cythonを始めたばかりです。私はまだ中級者ではありませんが、拡張機能を作成するのにははるかに使いやすいようです。numpy 配列の使用に関する例はたくさんあります。

これまでのところ、cython は、python のような構文のままで、python を自由に混在させることができるため、本当に優れていることがわかりました。ラッパーでコードを C に変換するのを支援するという点で、非常に多くの重労働を処理します。これは内部で行われます。また、生成された には中間の依存関係はありません.so。純粋な拡張機能です。

Python コードで numpy を使用する場合、変換を行う必要がないため、それらを拡張機能に渡すのは簡単です。numpy 自体は既に Python 側で大幅に高速化されていますが、追加のカスタム処理を行うと、numpy ポインターを cython 拡張側に渡すことができます。

于 2012-08-13T16:56:32.413 に答える