COMコンポーネントの設計と応用(七)――コンパイル、登録、呼び出し
8467 ワード
この文書は次のとおりです.http://www.vckbase.net/index.php/wv/1218
一、前言
前回はATLで最初のCOMコンポーネントプログラムを書きましたが、今回は主にコンパイル、ブック、呼び出し方法を紹介します.サンプルプログラムをダウンロードしましたか?まだダウンロードされていない場合は、vc 6.0のユーザーポイント、vc.netのユーザーポイントはこちらです.
二、コンパイルについて
2-1最小依存
「最小依存」は、コンパイラがATLで使用する必要がある関数の一部をターゲットプログラムに静的に接続することを示します.これにより、ターゲットファイルのサイズはやや大きくなりますが、独立性が強く、インストールが便利です.逆にシステムの実行にはATL.DLLファイルのサポートが必要です.「最小依存」に設定するにはどうすればいいですか?答えは、定義済みマクロ「_ATL_DLL」を削除し、操作方法は図1、図2を参照してください.
図一、vc 6.0での設定方法
図二、vc.net 2003において、設定方法
2-2 CRTライブラリ
ATLコンポーネントプログラムでCRTのランタイムライブラリ関数(例えば、sqrt()を2乗開く)が呼び出された場合、コンパイル時に「error LNK 2001:unresolved external symbol_main」とエラーが発生する可能性があります.どうしよう?定義済みマクロ「_ATL_MIN_CRT」を削除!操作方法も図1、図2を参照してください.(vc.net 2003のこの項目の属性は「ATLでCRTを最小使用する」と呼ばれています)
2-3 MBCS/UNICODE
これは言うまでもなく、事前定義マクロでは、それぞれ_MBCSまたは_UNICODE.
2-4 IDLのコンパイル
COMは設計初期に、言語間呼び出しを実現することを目標としていた.言語間である以上、コンポーネントのインタフェース記述は、どの言語環境でも認識されなければならない.どうしよう?.hファイルで説明する?------C言語プログラマーが笑って、便利ですね.BASICプログラマーは泣きました:-(そのため、マイクロソフトは新しいファイルフォーマット---IDLファイル(インタフェース定義記述言語)を使用しました.IDLはテキストファイルで、その言語文法は比較的簡単で、Cに似ています.具体的なIDLファイルの説明は、次の「COMコンポーネント設計と使用すべき(8)の新しいインタフェースの追加」を参照してください..IDLはコンパイルされ、バイナリを生成する等価型ライブラリファイルTLBが他の言語に提供されて使用される.図3は、ATL COMプログラムのコンパイルプロセスを示す.
図3、ATLコンポーネントプログラムのコンパイル過程
説明1:コンパイル後、タイプライブラリはTLBファイルとして単独で存在し、ターゲットファイルのリソースにも保存される.したがって、将来#importがタイプライブラリを導入する際に、TLBファイルを指定することも、ターゲットファイルを指定することもできる.
説明2:私たちはC/C++のプログラマーとして、まだ幸せです.IDLのコンパイル後、わざわざC言語形式のインタフェースファイルを提供してくれたからです.
説明3:IDLコンパイル後にエージェント/スタブソースプログラムを生成します.dlldata.c、xxx_p.c、xxxps.def、xxxps.makがあります.NMAKE.EXEで再コンパイルして、本物のエージェント/スタブDLLターゲットファイルを生成できます(注1).
三、登録について
状況1:ATLを使用してコンポーネントプログラムを作成する場合、登録は私たちが責任を負う必要はありません.コンパイルに成功すると、IDEは自動的に登録してくれます.
ケース2:MFCを使用してコンポーネントプログラムを作成する場合、コンパイラはあなたがCOMコンポーネントを書いているかどうか分からないため、自動的に登録することはできません.この場合、メニュー「ToolsRegister Control」を実行して登録することができます.
ケース3:COM機能を持つEXEプログラムを書くとき、登録する方法はこのプログラムを1回実行することです.
ケース4:サードパーティが提供するコンポーネントプログラムを使用する必要がある場合、コマンドラインに「regsvr 32.exeファイル名」を実行して登録することができます.ちなみに、逆登録の方法は「regsvr 32.exe/uファイル名」です.
ケース5:プログラム(インストーラなど)に登録する必要がある場合:
上記の例では、作業ディレクトリを切り替えるコード部分を簡略化できる場合が多いです.しかし、このコンポーネントをマウントする際に、依存しなければならないDLLを同時にロードする必要がある場合、自身のプログラムのBUGによって正しく位置決めできない可能性があります.咳......やはり自分で書いたプログラムで、そのエラーを補うようにしましょう......誰が私たちを良い人にしますか?ねえ、誰が私たちのレベルを彼より高くして、誰が私たちをvckbaseの上で“ランキングの目”にさせます......
四、コンポーネント呼び出しについて
総じて、コンポーネント・プログラムを呼び出すには、次のような方法があります.
#includeメソッド
IDLのコンパイル後、C/C++プログラマーの使用を容易にするために、xxx.hとxxx_i.cファイルが生成されます.私たちは本当に幸せで、直接#includeの後で使用することができます
#importメソッド
一般的な方法として、vcは包装クラスを生成し、呼び出しをより便利にします.
タイプライブラリパッケージクラスのロード方法
コンポーネントがIDispatchインタフェースを提供している場合は、この方法でコンポーネントを呼び出すのが一番簡単です.しかし、IDispatchはまだ話していません.後の文章を読むしかありません.
ActiveXパッケージのロード方法
ActiveXはまだ紹介されていないので、後で話しましょう.
サンプルプログラムをダウンロードしたら、使用方法を1つずつ参照してください.
例
方法
簡単な説明
1
#include
最も基本的なAPI方式でコンポーネントを呼び出し、呼び出し原理を熟知させる.
2
#include
ほとんどの場合、API方式を使用し、CComBSTRを使用して文字列の使用を簡略化します.
3
#include
スマートポインタCComPtr<>の使い方を示す
4
#include
スマートポインタCComPtr<>とCComQIPtr<>のブレンドの使用方法を示します
5
#include
スマートポインタCComQIPtr<>の使い方を示す
6
#include
スマートポインタの解放方法を示す
7
#import
vcパッケージのスマートポインタIxxxPtr、_bstr_t、_variant_tの使用方法と例外処理
8
#import
import後のネーミングスペースの使い方
サンプルプログラムにはコメントが書かれています.MSDNの関数の説明をよく読んで、参考にしてください.ここでは、「スマートポインタ」について説明します.
元のインタフェースポインタを操作するのが面倒なので、引用記数、API呼び出し、異常処理を自分で制御する必要があります.そこでATLは2つのスマートポインタのテンプレートパッケージクラス、CComPtr<>とCComQIPtr<>を提供し、この2つのクラスが宣言されています.CComQIPtr<>はCComPtr<>のすべての機能を含んでいるので、私たちは完全にCComQIPtr<>を使ってスマートインタフェースを使用することができますポインタ、唯一説明したいのは、CComQIPtr<>演算子のリロード機能を使用しているため、QueryInterface()関数を自動的に呼び出すことができます.そのため、CComQIPtr<>唯一の欠点は、IUnknown*ポインタを定義できないことです.
スマートポインタに値を割り当てる方法:
インテリジェントポインタが関数を呼び出す方法:
咳……言わないで、言わないで、みんなは多く本を読んで、多くMSNDを见て、多くサンプルのプログラムを见ましょう.书き疲れました:-(
五、まとめ
「COMコンポーネント設計と応用(八)」――ATLコンポーネントの第2のインタフェースを追加する方法に注目してください
注意1:プロキシ/スタブのコンパイル、vc 6.0では少々面倒ですが、「プロセス外コンポーネント」と「リモートコンポーネント」については後述します.vc.net 2003では、プロキシ/スタブが個別のプロジェクトとして自動的にソリューションに追加されるため、簡単です.
一、前言
前回はATLで最初のCOMコンポーネントプログラムを書きましたが、今回は主にコンパイル、ブック、呼び出し方法を紹介します.サンプルプログラムをダウンロードしましたか?まだダウンロードされていない場合は、vc 6.0のユーザーポイント、vc.netのユーザーポイントはこちらです.
二、コンパイルについて
2-1最小依存
「最小依存」は、コンパイラがATLで使用する必要がある関数の一部をターゲットプログラムに静的に接続することを示します.これにより、ターゲットファイルのサイズはやや大きくなりますが、独立性が強く、インストールが便利です.逆にシステムの実行にはATL.DLLファイルのサポートが必要です.「最小依存」に設定するにはどうすればいいですか?答えは、定義済みマクロ「_ATL_DLL」を削除し、操作方法は図1、図2を参照してください.
図一、vc 6.0での設定方法
図二、vc.net 2003において、設定方法
2-2 CRTライブラリ
ATLコンポーネントプログラムでCRTのランタイムライブラリ関数(例えば、sqrt()を2乗開く)が呼び出された場合、コンパイル時に「error LNK 2001:unresolved external symbol_main」とエラーが発生する可能性があります.どうしよう?定義済みマクロ「_ATL_MIN_CRT」を削除!操作方法も図1、図2を参照してください.(vc.net 2003のこの項目の属性は「ATLでCRTを最小使用する」と呼ばれています)
2-3 MBCS/UNICODE
これは言うまでもなく、事前定義マクロでは、それぞれ_MBCSまたは_UNICODE.
2-4 IDLのコンパイル
COMは設計初期に、言語間呼び出しを実現することを目標としていた.言語間である以上、コンポーネントのインタフェース記述は、どの言語環境でも認識されなければならない.どうしよう?.hファイルで説明する?------C言語プログラマーが笑って、便利ですね.BASICプログラマーは泣きました:-(そのため、マイクロソフトは新しいファイルフォーマット---IDLファイル(インタフェース定義記述言語)を使用しました.IDLはテキストファイルで、その言語文法は比較的簡単で、Cに似ています.具体的なIDLファイルの説明は、次の「COMコンポーネント設計と使用すべき(8)の新しいインタフェースの追加」を参照してください..IDLはコンパイルされ、バイナリを生成する等価型ライブラリファイルTLBが他の言語に提供されて使用される.図3は、ATL COMプログラムのコンパイルプロセスを示す.
図3、ATLコンポーネントプログラムのコンパイル過程
説明1:コンパイル後、タイプライブラリはTLBファイルとして単独で存在し、ターゲットファイルのリソースにも保存される.したがって、将来#importがタイプライブラリを導入する際に、TLBファイルを指定することも、ターゲットファイルを指定することもできる.
説明2:私たちはC/C++のプログラマーとして、まだ幸せです.IDLのコンパイル後、わざわざC言語形式のインタフェースファイルを提供してくれたからです.
説明3:IDLコンパイル後にエージェント/スタブソースプログラムを生成します.dlldata.c、xxx_p.c、xxxps.def、xxxps.makがあります.NMAKE.EXEで再コンパイルして、本物のエージェント/スタブDLLターゲットファイルを生成できます(注1).
三、登録について
状況1:ATLを使用してコンポーネントプログラムを作成する場合、登録は私たちが責任を負う必要はありません.コンパイルに成功すると、IDEは自動的に登録してくれます.
ケース2:MFCを使用してコンポーネントプログラムを作成する場合、コンパイラはあなたがCOMコンポーネントを書いているかどうか分からないため、自動的に登録することはできません.この場合、メニュー「ToolsRegister Control」を実行して登録することができます.
ケース3:COM機能を持つEXEプログラムを書くとき、登録する方法はこのプログラムを1回実行することです.
ケース4:サードパーティが提供するコンポーネントプログラムを使用する必要がある場合、コマンドラインに「regsvr 32.exeファイル名」を実行して登録することができます.ちなみに、逆登録の方法は「regsvr 32.exe/uファイル名」です.
ケース5:プログラム(インストーラなど)に登録する必要がある場合:
01.
typedef
HRESULT
(WINAPI * FREG)();
02.
TCHAR
szWorkPath[ MAX_PATH ];
03.
04.
::GetCurrentDirectory(
sizeof
(szWorkPath), szWorkPath );
//
05.
::SetCurrentDirectory( );
//
06.
07.
HMODULE
hDLL = ::LoadLibrary( );
//
08.
if
(hDLL)
09.
{
10.
FREG lpfunc = (FREG)::GetProcAddress( hDLL, _T(
"DllRegisterServer"
) );
//
11.
// , "DllUnregisterServer"
12.
if
( lpfunc ) lpfunc();
// 。 ,
13.
::FreeLibrary(hDLL);
14.
}
15.
16.
::SetCurrentDirectory(szWorkPath);
//
上記の例では、作業ディレクトリを切り替えるコード部分を簡略化できる場合が多いです.しかし、このコンポーネントをマウントする際に、依存しなければならないDLLを同時にロードする必要がある場合、自身のプログラムのBUGによって正しく位置決めできない可能性があります.咳......やはり自分で書いたプログラムで、そのエラーを補うようにしましょう......誰が私たちを良い人にしますか?ねえ、誰が私たちのレベルを彼より高くして、誰が私たちをvckbaseの上で“ランキングの目”にさせます......
四、コンポーネント呼び出しについて
総じて、コンポーネント・プログラムを呼び出すには、次のような方法があります.
#includeメソッド
IDLのコンパイル後、C/C++プログラマーの使用を容易にするために、xxx.hとxxx_i.cファイルが生成されます.私たちは本当に幸せで、直接#includeの後で使用することができます
#importメソッド
一般的な方法として、vcは包装クラスを生成し、呼び出しをより便利にします.
タイプライブラリパッケージクラスのロード方法
コンポーネントがIDispatchインタフェースを提供している場合は、この方法でコンポーネントを呼び出すのが一番簡単です.しかし、IDispatchはまだ話していません.後の文章を読むしかありません.
ActiveXパッケージのロード方法
ActiveXはまだ紹介されていないので、後で話しましょう.
サンプルプログラムをダウンロードしたら、使用方法を1つずつ参照してください.
例
方法
簡単な説明
1
#include
最も基本的なAPI方式でコンポーネントを呼び出し、呼び出し原理を熟知させる.
2
#include
ほとんどの場合、API方式を使用し、CComBSTRを使用して文字列の使用を簡略化します.
3
#include
スマートポインタCComPtr<>の使い方を示す
4
#include
スマートポインタCComPtr<>とCComQIPtr<>のブレンドの使用方法を示します
5
#include
スマートポインタCComQIPtr<>の使い方を示す
6
#include
スマートポインタの解放方法を示す
7
#import
vcパッケージのスマートポインタIxxxPtr、_bstr_t、_variant_tの使用方法と例外処理
8
#import
import後のネーミングスペースの使い方
サンプルプログラムにはコメントが書かれています.MSDNの関数の説明をよく読んで、参考にしてください.ここでは、「スマートポインタ」について説明します.
元のインタフェースポインタを操作するのが面倒なので、引用記数、API呼び出し、異常処理を自分で制御する必要があります.そこでATLは2つのスマートポインタのテンプレートパッケージクラス、CComPtr<>とCComQIPtr<>を提供し、この2つのクラスが宣言されています.CComQIPtr<>はCComPtr<>のすべての機能を含んでいるので、私たちは完全にCComQIPtr<>を使ってスマートインタフェースを使用することができますポインタ、唯一説明したいのは、CComQIPtr<>演算子のリロード機能を使用しているため、QueryInterface()関数を自動的に呼び出すことができます.そのため、CComQIPtr<>唯一の欠点は、IUnknown*ポインタを定義できないことです.
1.
// smart pointer, , sp
2.
CComPtr < IUnknown > spUnk;
//
3.
// IFun
4.
CComPtr < IFun > spFun;
//
5.
CComQIPtr < IFun > spFun;
//
6.
CComQIPtr < IFun, &IID_IFun > spFun;
//
7.
CComQIPtr < IUnknown > spUnk;
// !CComQIPtr IUnknown
スマートポインタに値を割り当てる方法:
01.
CComQIPtr < IFun > spFun;
// , , NULL
02.
03.
CComQIPtr < IFun > spFun( pOtherInterface );
// ,
04.
// pOtherInterface QueryInterface() IFun
05.
06.
CComQIPtr < IFun > spFun( spOtherInterface );
// ,
07.
// spOtherInterface QueryInterface() IFun
08.
09.
CComQIPtr < IFun > spFun ( pUnknown );
// , IUnknown QueryInterface() IFun
10.
11.
CComQIPtr < IFun > spFun = pOtherInterface;
// = ,
12.
spFun = spOtherInterface;
//
13.
spFun = pUnknown;
//
14.
15.
pUnknown->QueryInterface( IID_IFun, &sp );
// QueryInterface
16.
17.
// ,
18.
if
( spFun ){}
//
19.
if
( NULL != spFun ){}
//
20.
21.
if
( !spFun ){}
//
22.
if
( NULL == spFun ){}
//
インテリジェントポインタが関数を呼び出す方法:
01.
spFun.CoCreateInstance(...);
// API ::CoCreateInstance(...)
02.
spFun.QueryInterface(...);
// API ::QueryInterface()
03.
04.
spFun->Add(...);
//
05.
06.
// QueryInterface() , spFun.QueryInterface(...)
07.
spFun->QueryInterface(...);
08.
09.
spFun.Release();
// , NULL
10.
spFun->Release();
// !!! 。
11.
// , ( )
咳……言わないで、言わないで、みんなは多く本を読んで、多くMSNDを见て、多くサンプルのプログラムを见ましょう.书き疲れました:-(
五、まとめ
「COMコンポーネント設計と応用(八)」――ATLコンポーネントの第2のインタフェースを追加する方法に注目してください
注意1:プロキシ/スタブのコンパイル、vc 6.0では少々面倒ですが、「プロセス外コンポーネント」と「リモートコンポーネント」については後述します.vc.net 2003では、プロキシ/スタブが個別のプロジェクトとして自動的にソリューションに追加されるため、簡単です.