呼び出されるc関数は、以下の通り。
#include <stdio.h> typedef struct { char name[20]; int age; } NAMEandAGE; int sum_ages(int sz, NAMEandAGE *na) { int i; int sum = 0; for (i=0; i<sz; i++){ printf("%s %d\n", na[i].name, na[i].age); sum = sum + na[i].age; } return sum; }文字列と整数のフィールドをもつ、構造体NAMEandAGEの配列を渡して、 要素の値を表示し、ageの和を返す関数です。
配列は、pythonスクリプトで作成するため、その長さが分からないので、 整数szで長さを渡しています。
ソースファイルをstructures.cというファイルに保存して、
gcc -Wall -c structures.c
でコンパイルします。structures.oというオブジェクトファイルができますので、
gcc -shared -o structures.so structures.o
として、structures.soという、共有ライブラリファイルを作成します。
これを呼び出す、pythonスクリプトは、以下の通り。
import ctypes class NAMEandAGE(ctypes.Structure): _fields_ = [('name', ctypes.c_char*20), ('age', ctypes.c_int)] if __name__ == '__main__': mydll = ctypes.CDLL("structures.so") data = [('name1', 1), ('name2', 2)] nameandages = (NAMEandAGE * len(data))() for n, d in zip(nameandages, data): n.name = d[0] n.age = d[1] result = mydll.sum_ages(ctypes.c_int(len(data)), ctypes.pointer(nameandages)) print result配列は、(構造体のクラス * 要素数)で構造体配列のクラスを作って、それを用いてインスタンスを生成するようです。 その後、リストdataの値で、各要素のフィールドを設定しました。
関数を呼び出すときは、ctypes.pointer()を使って、構造体配列のポインタを渡せばよいようです。
0 件のコメント:
コメントを投稿