MLtonでWin32APIを呼び出す
Cygwin上のMLton*1でWin32APIを使用する簡単な例を紹介します。
以下の2つの例では異なる方法で右図のようなメッセージボックスを表示します。
コード全体はgistに置いてあります。
direct call
_import 式でシンボルと型を書くとお手軽に外部関数が使えます。
local val MessageBoxA = _import "MessageBoxA" stdcall: C_Pointer.t * string * string * Word32.word -> int; in val _ = MessageBoxA (C_Pointer.null, "Hello World!", "MLton Static FFI", 0w4096) end
indirect call
libdlを使って共有ライブラリから取り出した関数ポインタを呼ぶ方法もあります。
関数ポインタを呼び出す場合、 import式に `*' を指定します。
local val double_to_double = _import * : DynLink.fptr -> real -> real; val user32 = DynLink.dlopen ("user32.dll", DynLink.RTLD_LAZY) val sigMessageBoxA = _import * : DynLink.fptr -> C_Pointer.t * string * string * Word32.word -> int; val msgbox_ptr = DynLink.dlsym (user32, "MessageBoxA") val dynMessageBoxA = sigMessageBoxA msgbox_ptr in val _ = dynMessageBoxA (C_Pointer.null, "Hello World!", "MLton Dynamic FFI", 0w4096) val _ = DynLink.dlclose user32 end
ビルド
allowFFI を有効にしてビルドする必要があります。
# cat win32.mlb ann "allowFFI true" in $(SML_LIB)/basis/basis.mlb $(SML_LIB)/basis/mlton.mlb $(SML_LIB)/basis/c-types.mlb dynlink.sml win32.sml end # mlton win32.mlb