目次
GHCは、Haskell 98の追補である他言語関数インタフェース1.0に(大部分)準拠している。これの定義はhttp://www.haskell.org/
から得られる。
GHCでFFI対応を有効にするには、-XForeignFunctionInterface
フラグを与えれば良い。
GHCには、FFI追補に対する固有の拡張がいくつか実装されている。これらの拡張は8.1. FFI追補に対するGHCの拡張に記述されている。これらの拡張を使ったプログラムは可搬でないということにどうか気を付けてほしい。従って、これらの機能は可能な限り避けるべきである。
FFIライブラリの説明は一緒に配布されているライブラリ説明書にある。例えばForeign
モジュールを見よ。
この節で説明するFFIの機能はGHC特有のものである。これらを使った場合、他のコンパイラに対する可搬性がなくなる。
基本他言語型(FFI追補の3.2節を見よ)として、以下の型を使える。Int#
、Word#
、Char#
、Float#
、Double#
、Addr#
、StablePtr# a
、MutableByteArray#
、ForeignObj#
、ByteArray#
。
FFIの仕様は、種々の箇所にIOモナドが現れることを要求するが、次のようにIOモナドをnewtype
で包むのが便利なことがある
newtype MyIO a = MIO (IO a)
(このようなことをする理由としては、例えば、プログラムのある場所において、任意のIO手続きを呼ばれることを防ぎたい、というのが考えられる)
Haskell FFIは既に、他言語にインポート・エクスポートされるものの引数や結果がnewtypeだった場合、それらは自動的に外される、としている(FFI追補の3.2節)。GHCはこれを拡張して、IOモナド自体を包むnewtypeも自動的に外す。より正確にいうと、FFIの仕様がIO型を要求しているところならどこでも、IO型をnewtypeで包んだ物も認める。例えば、以下の宣言は問題ない。
foreign import foo :: Int -> MyIO Int foreign import "dynamic" baz :: (Int -> MyIO Int) -> CInt -> MyIO Int
GHCはFFIを拡張して、prim
という呼び出し規約を追加している。例をあげる。
foreign import prim "foo" foo :: ByteArray# -> (# Int#, Int# #)
これは、GHCの内部的な呼び出し規約に従う、Cmmコードで書かれた関数群をインポートするのに使う。この機能は、専らGHC付属の中核ライブラリでのみ使うことを意図している。さらなる詳細はGHC開発者wikiを見よ。