1

私は、最初のアウトプロセス COM サーバーを実装している最中です (つまり、最初の COM サーバーです)。IDL ファイルを作成し、プロキシ/スタブ DLL のコードを生成し、DLL をコンパイルして登録する手順に従いました。

レジストリキーを確認すると、

  • という名前のキーでHKEY_CLASSES_ROOT/Interface/<GUID>、その値は (たとえば)IMyAppであり、
  • という名前のキーでHKEY_CLASSES_ROOT/Interface/<GUID>/ProxyStubClsid32、その値は です<GUID>。つまり、キー名と同じ値です。

2番目のキーの値がキー名と同じ値になる方法がわかりません<GUID>。現在の理解では

  • ではHKEY_CLASSES_ROOT/Interface/<GUID>、GUID はインターフェイスIDです。
  • ProxyStubClsid32インターフェース ID ではなく、上記のインターフェースを実装するコンポーネントを参照するクラスID です
  • HKEY_CLASSES_ROOT/CLSID/<GUID>/InprocServer32(GUID は上記のクラスID)の値は、プロキシ DLL を指します。

HKEY_CLASSES_ROOT/Interface/<GUID>/ProxyStubClsid32では、1 つがインターフェイス ID で、もう 1 つがクラス ID である場合、どのようにして の値が同じ値の GUID を保持できるでしょうか?

編集:私はまだこれに対する答えを望んでいます。簡単に言うと、コンポーネントとインターフェースは 2 つの異なるものなので、同じ ID を両方に使用するにはどうすればよいでしょうか?

4

3 に答える 3

7

COM での Guid の使用方法に関する基本的な理解は正しいです。最初に注目すべきは、インターフェイスとコクラスが同じ GUID を持つことは問題ではないということです。それらは異なるレジストリ キー (HKCR\Interface と HKCR\CLSID) に存在し、IID と CLSID のどちらを検索しているかは常に COM で明確です。

2 番目は、作成した IDL です。プロキシの CLSID を指定する場所がないことに注意してください。ここでは、プロキシとスタブでサポートされている IID のみを宣言できます。

次に、プロキシ/スタブが自動生成される方法でワイルド グース チェイスが必要です。Windows SDK のコア ヘッダーは RpcProxy.h です。これをテキスト エディターで開いて確認してください。マクロ スープは非常に重いですが、何が起こっているかを説明する適切なコメントがいくつかあります。重要な RPC ヘルパー関数は NdrDllRegisterProxy() です。これはプロキシを登録し、Regsvr32.exe を使用するときに呼び出されます。3 番目の引数は、プロキシの CLSID を指定します。私はあなたに読んでもらい、.h ファイルの重要な部分を引用します:

コンパイラ スイッチ:

-DPROXY_CLSID=clsid
    Specifies a class ID to be used by the proxy DLL.

これは、Project + Properties、C/C++、Preprocessor、Preprocessor Definitions 設定で指定します。プロジェクトでは指定されないことに注意してください。

スープを追いかけると、次のスープにたどり着きます。

// if the user specified an override for the class id, it is
// PROXY_CLSID at this point

#ifndef PROXY_CLSID
#define GET_DLL_CLSID   \
    ( aProxyFileList[0]->pStubVtblList[0] != 0 ? \
    aProxyFileList[0]->pStubVtblList[0]->header.piid : 0)
#else  //PROXY_CLSID
#define GET_DLL_CLSID   &PROXY_CLSID
#endif //PROXY_CLSID

つまり、CLSID を自分で指定しなかった場合 (指定しなかった場合) 、スタブ テーブルの最初のIIDが使用されます。

これにより、ProxyStubClsid32 GUID が最初のインターフェイスの IID と同じになります。機能であり、バグではありません。

于 2012-10-27T14:53:34.230 に答える
0

初心者の混乱 (tm) のケース。呼び出して登録したクラスは、私のCLSIDregsrv32のものではありません。これは、プロキシ/スタブ DLL 用に特別に生成されたものです (フレンドリ名 PSFactory もこれを示しています)。Roman R. が推測したように、1 つしかないと思っていたクラスが 2 つあるのです。自分の CLSID は、スイッチで呼び出されたときに EXE サーバーによって登録されます。/Embedding

于 2012-10-29T18:40:17.260 に答える