2006 年 11 月 27 日 23 時 48 分

クラス ID の割り当て


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


[写真]


クラスオブジェクトが完成した。
これをクライアントに公開するためには、
クラスに一意のクラス ID を割り当てる必要がある。

これは、guidgen などのコマンドを使えば生成できる。
プログラム的に作成したい場合は、
CoCreateGuid API を呼び出しても取得できる。

guidgen を使った場合は、生成した ID を
C++ のソースに書ける形でクリップボードにコピーできる。

// {755525B6-51FB-490b-A21B-91F7208C9429}
static const GUID <<name>> =
{ 0x755525b6, 0x51fb, 0x490b, { 0xa2, 0x1b, 0x91, 0xf7, 0x20, 0x8c, 0x94, 0x29 } };

これをソースファイルにコピーし、
<<name>> の部分を、CLSID_HardLinkIconID に書き換えると、
すぐにコードとして利用できるようになる。

クラス ID は複数のソースから参照されるので、
ヘッダファイルに格納するのが一般的だが、
上記の場合、static const となっているので、
ソースファイル内でのみ使える定数を定義する事になる。

static がついている場合、内部リンケージとなり、
複数のソースファイルでヘッダファイルを利用した場合、
ソースファイル毎に実体が作成される。
その数だけメモリが消費されてしまうことになる。

GUID は 16 バイトなので、それほどは大きくないし、
変数ではなく定数なので実害は少ないが、
複数のソースファイルから参照されることを考えて、
実体を 1 つだけにしておきたい。

本来は、この COM サーバを使う C++ クライアントの為に、
依存性のない専用のヘッダファイルに格納すべきだが
今回は手を抜いて、global.hpp と global.cpp に入れよう。
後で分離することはそれほど難しくない。

まずは宣言を global.hpp に書く。

========== global.hpp ==========

//(…前略…)

// グローバル変数
extern HMODULE g_moduleHandle;
extern ULONG g_serverLockCount;

// グローバル定数
extern const GUID CLSID_HardLinkIconID;

#endif // !global_hpp_included

========== end of global.hpp ==========

続いて、実体を global.cpp に定義する。

========== global.cpp ==========

//(…前略…)

// グローバル変数の実体
HMODULE g_moduleHandle = NULL;
ULONG g_serverLockCount = 0;

// グローバル定数の定義(実体)

// {755525B6-51FB-490b-A21B-91F7208C9429}
extern const GUID CLSID_HardLinkIconID =
{ 0x755525b6, 0x51fb, 0x490b, { 0xa2, 0x1b, 0x91, 0xf7, 0x20, 0x8c, 0x94, 0x29 } };

========== end of global.cpp ==========

C++ ではグローバル定数を定義する場合は、
変数と違って extern の明示が必要となる。

ファイルスコープで extern も static も省略した場合は、
デフォルトのリンケージが使われるのだが、
C の既定値は定数も変数も extern であるが、
C++ では定数が static で変数が extern だからだ。

C++ には名前空間があるので、
static/extern を意識して使うことは少ないが、
C 風のコードも利用する C++ 開発の場合は、
リンケージに注意する必要がある。

今回は global.cpp も global.hpp を取り込んでおり、
global.hpp でリンケージが extern と明示されているため、
extern を省略しても外部リンケージとなるが、
定数定義だけ移動したりコピーしたりすることを考え、
extern をつけておいたほうが無難である。

上記の定義により、CLSID_HardLinkIconID を、
グローバル定数として使えるようになった。

この CLSID_HardLinkIconID は、
HardLinkIconID クラスを表す一意の ID であり、
クライアントがクラスを要求する際に利用される事になる。



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