DLLからシンボルがエクスポートされていれば、HaskellからFFIで呼び出せることが分かりました。独自言語(Andromeda)で開発した簡易リンカでDLLを出力してHaskellから呼び出してみました。
※独自言語はEXEしか出力できないため、独自言語から直接DLLをコンパイルするのではなく、リンカを作ってDLLを出力しています。
実際にリンカをビルドしてDLLを出力できるようにまとめたセットを用意しました。コンパイラがバンドルされているので、.NET Framework 3.5環境ではすぐに試せるようになっています。
リンカのコード
helloというシンボルをエクスポートしたDLLを出力するコードは以下の通りです。
var exe = new PEModule; exe.File.Characteristics |= IMAGE_FILE_DLL; exe.WinNT.SubSystem = IMAGE_SUBSYSTEM_WINDOWS_GUI; var text = new Block; var MessageBoxW = new OpCode; // DllMain() text.AddOpCode(I386.Ret); // hello() exe.Export("hello", text.CurrentAddress); text.AddOpCode(I386.PushD(1)); text.AddOpCode(I386.PushAd(exe.GetString("だいあろぐ"))); text.AddOpCode(I386.PushAd(exe.GetString("こんにちは、世界!"))); text.AddOpCode(I386.PushD(0)); text.AddOpCode(I386.Call(MessageBoxW)); text.AddOpCode(I386.Ret); text.AddOpCode(MessageBoxW); text.AddOpCode(I386.JmpAd(exe.Import("USER32.DLL", "MessageBoxW"))); var dll = "hello.dll"; exe.WriteFile(dll, text, true); println(); printfln(dll + " を出力しました。"); pause();
呼び出すHaskell側は前回と同じです。