こんにちは。早川です。

FFI で遊んでみました。結果は..

$ cat foreign.hs
module Main where

foreign import ccall "foo_from_c" foo  :: IO ()
foreign export ccall "foo" foo_from_hs :: IO ()

foo_from_hs = putStrLn "foo from Haskell!"
main = foo

$ cat foo.c
#include <stdio.h>

void foo_from_c() {
    printf("foo from C!\n");
    foo();
}

$ !ghc -fglasgow-exts -o foreign foreign.hs foo.c
$ ./foreign
foo from C!
foo from Haskell!

ちょっと感動です (^^;
関数の import, export は問題ありませんでした。
-- しかもめちゃ手軽!

あまりに簡単にできるので Perl を組み込んでみました。

$ cat perl.hs
module Main where

import Foreign
import Foreign.C

type PERL = Ptr ()
foreign import ccall "perl_alloc" perl_alloc :: IO PERL
foreign import ccall "perl_construct" perl_construct :: PERL -> IO ()
foreign import ccall "perl_parse" perl_parse :: PERL -> FunPtr ()
    -> Int -> Ptr CString -> Ptr CString -> IO ()
foreign import ccall "perl_run" perl_run :: PERL -> IO ()
foreign import ccall "perl_destruct" perl_destruct :: PERL -> IO ()
foreign import ccall "perl_free" perl_free :: PERL -> IO ()
foreign import ccall "Perl_eval_pv" eval :: PERL -> CString -> Int
    -> IO (Ptr ())
foreign import ccall "&xs_init" xs_init :: FunPtr ()

main = do
    my_perl <- perl_alloc
    perl_construct my_perl
    argv <- mkEmbeddingArg
    perl_parse my_perl xs_init 3 argv nullPtr
    perl_run my_perl
    --str <- newCString "print 'Hi!^-^!'"
    str <- newCString $
        "use LWP::Simple;" ++
        "print get 'http://haskell.org/';"
    eval my_perl str 1
    perl_destruct my_perl
    perl_free my_perl
    where
        mkEmbeddingArg = do
            a1 <- newCString ""
            a2 <- newCString "-e"
            a3 <- newCString "0"
            newArray [a1, a2, a3]

$ cat xs_init.c
#include <EXTERN.h>
#include <perl.h>

EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);

EXTERN_C void
xs_init(pTHX)
{
    char *file = __FILE__;
    newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
}

$ ghc -fglasgow-exts -o try_perl perl.hs xs_init.c -optc '`perl \
-MExtUtils::Embed -e ccopts`' -optl '`perl -MExtUtils::Embed -e ldopts`'
$ ./try_perl
-- http://haskell.org/ の webページを出力

まだ experimental なのかな?と勝手に思い込んでいたのですが
十分実用レベルだったんですねー
-- H/Direct はなぜかビルドできないのですが、これなら必要なさそう

--
SH
tetryl / tokyoprogrammer.com


--
ML: haskell-jp / quickml.com
使い方: http://QuickML.com/