C#2.0時代のゲームプログラミング(7)

file systemの話が出たので、ついでにdllのpathの設定の話。


yanesdk.dllから利用しているsdl関連のdllだけで、sdl.dll , sdl_image.dll , sdl_mixer.dll , libpng.dll , zlib.dll , sdl_ttf.dllなど多数必要になる。これらが実行フォルダに入っていると邪魔である。この配置フォルダをlibフォルダにしたい。


これが結構難しい。たとえば、dllが見つからなかったときのハンドラを書けばいいと思うかも知れない。




public static void SetDllPath(string lib)
{
AppDomain.CurrentDomain.AssemblyResolve
+= new ResolveEventHandler(
delegate(object sender, ResolveEventArgs args)
{
string[] files = args.Name.Split(new char[] { ',' });
// 無限再帰になってたりして?
if (files[0].Length >= 256)
throw new DllNotFoundException("DLL: "+lib+
Path.PathSeparator+files[0] + ".dllが見当たらない");
byte[] dll = File.ReadAllBytes
(lib + Path.DirectorySeparatorChar + files[0] + ".dll");
Assembly asm = Assembly.Load(dll);
return asm;
}
);
}


ちょっと書いてみたが、これはダメだ。sdl_image.dllが内部的にlibpng.dllやzlib.dllを読み込むのだ。(おそらくsdl_image.dll内部のLoadLibraryで)


よって、lib/sdl_image.dllを読み込むところまでは出来ても、libpng.dllを読み込むときにlib/libpng.dllではなく./libpng.dllを読み込みに行ってしまう。意外とこの問題は嫌らしい。


もっとも、上の方法自体は有用で、他のdllに依存しないdllを、zipフォルダにまとめてみたり、Yanesdk.dllの後ろにバイナリとしてくっつけておいて、それを読み出して使うなどと言ったことも出来る。*1


(つづく)

*1:LGPLのdllだとこんなことしてはlicense違反のような気もするが…。