ctypesで定義した構造体の配列を初期化する
PythonからWin32API
を直接叩きたい機会があったのですが、PyWin32
に使いたかったRAWINPUT
周りの構造体や関数が用意されていなかったため、ctypes
から使用することにしました。当然Cの引数や返り値をラップする必要がでてくるわけですが、見かけた構造体の配列の初期化の構文で一瞬むむ??っとなったのでメモです。
ctypesのリファレンスの例を借りると、構造体の配列は
from ctypes import * class POINT(Structure): _fields_ = ("x", c_int), ("y", c_int) TwoPointsArrayType = POINT * 2 array = TwoPointsArrayType(POINT(1,2),POINT(3,4))
という風に書けるわけですね。ただ、任意の数のPOINT配列を作りたいなぁというときに、わざわざ配列タイプをtypedef
するのも面倒なので一行で書きたくなるわけです。
そうするとこうなります。
# 10個のPOINTを含むリスト p_list = [] for i in range(10): p_list.append(POINT(i,i)) # ctypeで使う配列 array = (POINT*len(p_list))(*(p for p in p_list))
一瞬C言語のポインタ表現かと見間違えました笑。リストを*
で展開して初期化の引数に渡してあげているんですね。慣れればなんてことないですが、初めて見るとなんだこれとなったのでメモでした!