MASATOの開発日記 2001年4月


4/30(NEW)

オブジェクト指向は長距離ランナーに似ている。 関数型は中距離ランナー。手続き型は短距離ランナーである。

真面目にオブジェクト指向で書くと最初から開発が遅い。 すごい遅い。よりオブジェクト指向っぽく書くとより遅い。 だけどそのペースがいつまでたってもほとんど落ちない。
関数型で書くと、最初は速いが、途中から辛くなり、最後にはもう勘弁してという 状態になる。
どれが優れているというわけではなく、いわゆる適材適所。 一時間程度で完成させたい短いプログラムにオブジェクト指向を持ちこむのは かえって遅くなるだけである。
私も時々WinMainだけのプログラムを書く。
また、オブジェクト指向といっても簡単には使えない。 オブジェクト指向のつもりだったけれど、いざ作ってみたら途中でスパゲッティになってしまった ということは良くある。 つまり、ちゃんとオブジェクト化されていなかったわけだ。
「どこまで開発ペースを落とさずにいられるか」これが、どのくらい良くオブジェクト指向の概念が 使われているのかを測るベンチマークとなるだろう。

(Visual C++)実行可能なデーターを出力する方法(その2)。

さてさて前回の続きです。前回は、実行可能なデーターを

  1. 前もって用意しておいたexe。
  2. データー。(データーの先頭には識別子)
  3. データーサイズ。
の順番で出力することを説明しました。 今回は、一番最初の「前もって用意しておいたexe」について説明します。

要は、このexeは、自分自身を開いてデーターを読み取る実行ファイルです。 読み取り部分のコードは次のようになります。

TCHAR path[MAX_PATH];
CFile file;
if (!::GetModuleFileName(::AfxGetInstanceHandle(), path, sizeof(path)) > 0
    || !file.Open(path, CFile::modeRead | CFile::shareDenyWrite)){
    // ●自分自身が開けない。エラー●
}
DWORD filelen = file.GetLength();
if (filelen < 4){
    // ●エラー●
}
file.Seek(filelen - 4, CFile::begin);
DWORD datalen;
file.Read(&datalen, sizeof(datalen));
if (datalen + 4 >= filelen){
    // ●エラー●
}
file.Seek(filelen - 4 - datalen, CFile::begin);
LPVOID mem = malloc(datalen);
file.Read(mem, datalen);
CMemFile memfile((LPBYTE)mem, datalen);
CArchive ar(&memfile, CArchive::load);
// ●arからデーターを読み取る。●
// ●先頭が識別子であるかどうかをチェックすること。●
自分自身(実行ファイル)を開く際には、shareDenyWriteを指定しないと、開けません。 これは既にOSによって実行ファイルが開かれているからでしょう。 あとは、ファイルサイズやデーターサイズが不正な値でないか調べているだけです。

これで、exeファイルにデーターを付加する方法と、 exeファイルから自分自身に付加されたデーターを読み取る方法を書きました。 これでばっちり自己解凍書庫が作れますね。
自己解凍書庫以外にもさまざまな応用が効きます。例えば、実行可能な差分ファイルや、 インターネットから自動的に差分を落としてくるようなアプリケーションです。 (この場合はURLが付加されるデーターになります。)
こういったファイルは、ファイルサイズが小さい事が望ましいので、 非MFCで作るというのも良いでしょう。上記したプログラムではMFCを使ってますが、 たいしたものではありませんので非MFCに直すのも簡単でしょう。


masato@mb.kcom.ne.jp