Cからhaskellを使う
またまた備忘録
haskellでオブジェクトファイル作ってそいつをcから利用する方法。
備忘録なんでずいぶん適当。
まずはhaskellで何か書く
module Fib where foreign export stdcall fib :: Int -> IO Int fib :: Int -> IO Int fib n = return . head . drop n $ fib' where fib' = 1:1:[a + b | (a, b) <- zip fib' $ tail fib']
モジュール名を明記してやって、foreign exportの行を書く。
この辺は決まり文句らしい。
ん?stdcallじゃなくてccallにすべきなのかも。まぁ、動いたからいいや。
やってることは単純にフィボナッチ数列のn番目を引っ張ってくるだけ。
もちっと賢い方法あるのだろうけどキニシナイ。
あと、Cに渡されるのはIntになる。この場合。
一節によるとCIntとかCに渡すための型があるらしいのだが、その辺はGHCがよきに計らってくれるらしい。
多分真面目にやるんだったらForeign.Cあたりをimportしなくちゃいけないんだろうけど。
配列とか文字列を買えしたいときも同様。
あとGHCの独自拡張とかあるらしいけどキニシナイ。
あとCの方
#include "test_stub.h" #include <stdlib.h> #include <stdio.h> #ifdef __GLASGOW_HASKELL__ extern void __stginit_Fib ( void ); #endif int main( int argc, char** argv ) { int i = 0; if( argc > 1 ) { i = atoi( argv[1] ); } hs_init( &argc, &argv ); #ifdef __GLASGOW_HASKELL__ hs_add_root( __stginit_Fib ); #endif printf( "%lu\n", fib( i ) ); hs_exit(); return 0; }
test_stub.hはghcが勝手に作ってくれるので気にしない。(test_stub.cも発生。
__GLASGOW_HASKELL__はghc独自。hugsの場合はよく分からない。FFIとか仕様があるらしい。
まぁ、こんな感じ。
コンパイル方法は
$ ghc -c -o test.o test.hs -fglasgow-exts $ ghc -c -o main.o main.c $ ghc -c -o test_stub.o test_stub.c $ ghc -o main *.o
こんな感じ。
スマートなMakefileの書き方が思いつかない...(д)