ポインタで値を受け取る関数のFFI
C言語は、言語の都合上、関数へ渡したアドレスを用いて戻り値を受け取ることがしばしばあります。
extern "C" void ReceivePointer( int* p ) { *p = 100; }
これをHaskellで受け取るために、次のような手順をとります。
- allocaでスタック上にメモリを割り当てる
- Cの関数へポインタを渡して値を受け取る
- ポインタ先の値をpeek関数で取得
- (alloca関数が終わるのでメモリが開放される)
型が理解しやすくなるように関数を分割して記述するとこんな感じ。
{-# LANGUAGE ForeignFunctionInterface #-} import Foreign.Storable import Foreign.Marshal import Foreign.Ptr foreign import ccall "ReceivePointer" c_ReceivePointer :: Ptr Int -> IO () receiveAction :: Ptr Int -> IO Int receiveAction px = c_ReceivePointer px >> peek px receive :: IO Int receive = alloca receiveAction main :: IO () main = receive >>= print