Cは高速で計算できて良いのだけども、なにかを少し変えるごとにいちいちコンパイルしなおしてというのがちょっと面倒に感じるとことがあります。
そこで定型の計算のモジュールをCで用意し、UIやSensor I/OをPythonで行ない、PythonからCのモジュールを呼び出して計算を行ない、UIやSensor I/Oの変更はPython上で柔軟に行なうということをやってみましたところ意外と簡単で便利そうなので投稿してみました。
以下が定型計算のCのソースです。引数はa,bの入力と戻り値用のポインタ retPointerで、戻り値はreturnからのtmp2とretPointerに入れこんだtmp1です。
#include <stdio.h>
double test(double a, double b, double *retPointer ){
double tmp1 = a * b;
double tmp2 = a / b;
*retPointer = tmp1;
return tmp2;
}
これをコンパイルするときに以下のように.so (shared object)を出力します。
$ gcc -shared -o pyTest.so pyTest.c
そしてpython側はctypesというライブラリをimportしてpyTest.soに対して引数と戻り値をそれぞれ定義し、a,bの入力をinp1,inp2のfloat数からctypeのdoubleに変換し、また戻り値用のポインタをretで定義しています。
そうした上でretValue = libtest.test(inp1,inp2,ret)を実行することでinp1,inp2,retが引数として渡され戻り値(return)はretValueに代入され、またポインタ(ret)には別の戻り値が返されます。
注意点としてpythonのfloatはCではdoubleになります。
import ctypes
libtest = ctypes.CDLL("./pyTest.so")
libtest.test.argtypes = [ctypes.c_double,ctypes.c_double\
,ctypes.POINTER(ctypes.c_double)]
libtest.test.restype = ctypes.c_double
ret=ctypes.c_double()
a=input("a?: ")
b=input("b?: ")
inp1 = ctypes.c_double(float(a))
inp2 = ctypes.c_double(float(b))
retValue = libtest.test(inp1,inp2,ret)
print("a= ",a," b= ",b)
print("a * b = ",ret.value)
print("a / b = ",retValue)
以下が実行結果で 3 , 7 の入力に対して掛け算と割り算の結果が表示されてます。
a?: 3
b?: 7
a= 3 b= 7
a * b = 21.0
a / b = 0.42857142857142855
今回はLinux(ubuntu)上でコンパイル・実行しました。Windows上でもDLLで同じような操作ができるということですが試していません。
もしWindows上でやってみた方がいればコメントいただければうれしいです。
以上
STM