2005-09-18 [長年日記]

_ [C#] ImageView

先週からC#で作っている画像表示アプリはとりあえずImageViewという名前にしてみた。現在のところ、ファイルをD&Dしたらそのファイルを表示、フォルダをD&Dしたらその中の画像を順に表示、画像はウィンドウサイズにアスペクト比を保ったままで拡大縮小する、といったところまで出来ている。画像のデコードは.NET Frameworkに付いているJPEGとかPNGのデコーダーをそのまま利用、拡大縮小はバイキュービックが使えるので画質的には問題が無い表示ができている。

今日取り組んだのがLHAやZIPでまとめられたファイルをそのまま表示する機能。画像表示アプリとしては一般的な機能だ。アーカイブファイルの展開はUnlha32.dllなどを使うので特に難しくは無いが、こだわったのがアンマネージなDLLファイルをハンドリングする方法だ。C#では一般的に[DllImport]を使ってアンマネージなDLLを使えるようにするが、それだとアーカイバが提供する機能をハンドリングをするのに非常に多くの[DllImport]を書かなければならず美しくない。C++やDelphiだとLoadLibraryとGetProcAddressを使ってダイナミックリンクする方法が取れるが、C#ではGetProcAddressで取得したメソッドのアドレスを実行する方法が無い(全く無いわけではない。ここなど参照)。

しかし今回使っているのはVisual Studio 2005のため、.NET Frameworkは2.0となる。2.0からはこのGetProcAddressで取得したメソッドのアドレスを実行する方法が提供されている。詳しくはここなどを参照するとよい。結構おまじないとして書かなければならないコードが多いので、今回の統合アーカイバAPI仕様のDLLを扱うときのようにGetProcAddressが効率よく使える場合でなければ面倒が増えるだけかもしれない。でも「DLLがあれば使う」というタイプのコーディングができるので、使える場面は結構ありそう。

結局ImageViewではUnlha32とUnzip32だけを使うようにしてあるが、他のDLLを使うようにするのも簡単。アーカイブファイルの中のファイルの取り出しもメモリ経由で行うようにしたのでそれなりに効率は良いはず。ただ、どうしても正しく表示できないファイルがあり、検証したところアーカイブ内にフォルダが作られているタイプのzipで問題が出ている模様。同じフォルダ構成でlhaでは問題が出ていないので、zip固有の問題なのかも知れず。

次なる実装点として考えているのが速度の向上とコマンドラインからのファイル投入。コマンドライン処理を入れるまえに現在のクラス構造を見直したいところではある。速度向上はマルチスレッドによって次のファイルを事前デコードするようにしようかと思っているが、Unlha32.dllはスレッドセーフじゃないということでうまく出来るかどうか不明。

_ アーカイバ

今回統合アーカイバプロジェクトなどからアーカイバの情報を集めていたが、設計がかなり古い。互換性を重視してこのようになっているのだとは思うが、せめてスレッドセーフな設計、完全UNICODE化、COMインターフェース化などを進めてもいい頃じゃないかと思う。まあこのあたりの開発メーリングリストに参加しているわけでもないのでもしかしたら何か進行しているかもしれないが。

過去の互換性に問題が出るなら新しいアーカイバでも良いような気がするが、さすがに使ってくれる人は少ないかな。こういうのはどれだけ普及できるかがキモなので。

[]

トップ «前の日記(2005-09-17) 最新 次の日記(2005-09-23)»