タイトル通りです。numba.cfuncを利用するとJITコンパイルした関数のアドレスが取れるので、それをC言語で書かれたライブラリの関数に渡します。
C言語側
sample.c
int apply(int (*callback)(int, int))
{
return callback(1, 2);
}
Linuxであれば、これを
gcc -shared -fPIC -o libsample.so sample.c
でビルドして共有ライブラリを作ります。
Python側
main.py
from numba import cfunc
import ctypes
# ここではmain.pyとlibsample.soを同じディレクトリに置く想定
lib = ctypes.cdll.LoadLibrary("./libsample.so")
callbackType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_int32, ctypes.c_int32) # (戻り値, 引数1, ...)
lib.apply.argtypes = (callbackType,)
lib.apply.restype = ctypes.c_int32
# この関数をCに渡す
@cfunc("int32 (int32, int32)")
def add(x, y):
return x + y
if (__name__ == "__main__"):
print(lib.apply(add.ctypes))
main.py
を実行すれば、add
関数がapply
関数からコールバックされ、3と表示されます。
参考文献
環境
Ubuntu 22.04 on WSL2(Windows11)
Python 3.10.12
Numba 0.60.0
GCC 11.4.0