呼び出される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 件のコメント:
コメントを投稿