2007 年 8 月 26 日 23 時 16 分

ホストの作成 #2: scrnsave.lib 互換モジュール


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


最初は、module.cpp を作る。
Application クラスのメソッドを呼ぶだけなので単純だ。

========== module.cpp ==========

#include "config.hpp"
#include "Application.hpp"

#pragma unmanaged

// Application インスタンス
// ファイルプライベート(手抜き)
namespace {
    Loafer::ScreenSaver::Host::Application application;
}

BOOL WINAPI RegisterDialogClasses(HANDLE hInst) {
    return application.RegisterClasses(hInst);
}

BOOL WINAPI ScreenSaverConfigureDialog(
        HWND hdlg, UINT message,
        WPARAM wParam, LPARAM lParam) {
    return application.ConfigureProc(
            hdlg, message, wParam, lParam);
}

LRESULT WINAPI ScreenSaverProc(
        HWND hwnd, UINT message,
        WPARAM wParam, LPARAM lParam) {
    return application.MainProc(
            hwnd, message, wParam, lParam);
}

========== end of module.cpp ==========

Application クラスのインスタンスを用意し、
DLL 用の関数呼び出しをそのメソッドに委譲する。
これは、scrnsave.lib の仕様を満たすためだけのコードだ。

さて、最初に追加したプラグマ命令 unmanaged は、
そのプラグマ直後のソースコードを、
ネイティブの C++ でコンパイルすることを指定している。

C++/CLI を有効にしてコンパイルする場合、
既定では、できる限りのコードが CLI 互換に変換される。
つまり、CLI の中間言語(CIL)が出力されてしまうのだ。

今回のようなケースでは、CLI の利用は必要最小限にしたい。
そこで、#pragma unmanaged を指定しておけば、
純粋な C++ としてコンパイルされ、機械語が出力される。

では、このソースをコンパイラにかける。
C++/CLI を使うには、/clr スイッチを追加するだけだ。

$ cl /c /W4 /clr /Fomodule.obj module.cpp

#pragma unmanaged を指定しているので、
/clr スイッチは実質意味がないようにも見えるが、
このスイッチは、他のコンパイラオプションに影響を及ぼす。

そのため、ソースコードをコンパイルする際には、
なるべく同じコンパイラオプションを使っておかないと、
リンク時や実行時に障害が発生する可能性が高くなる。
(実際、CLR 環境や C ランタイムでトラブルの元になる)

これで、module.obj ができた。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.