[ 前のページ ]
[ 次のページ ]
[ 目次 ]
[ 索引 ]
[ DOC Home ]
この章では,OpenVMS用のCOMアプリケーションの開発方法について説明します。
DCOM$EXAMPLES:[SAMPLE1] DCOM$EXAMPLES:[SIMPLE] DCOM$EXAMPLES:[DISPATCH_SAMPLE1]
SAMPLE1
とDISPATCH_SAMPLE1
は,Microsoft
Pressから出版されているDale Rogerson著『Inside COM』という書籍からの抜粋です。
この書籍はCOMアプリケーションを開発する際に非常に役立つ参考文献です。
ここでは,COM for OpenVMSアプリケーションの作成方法について説明します。
16バイトのグローバル一意識別子(GUID)を生成するには,
DCOM$GUIDGEN
ユーティリティを使用します。このユーティリティはOpenVMS
スタイルとUNIXスタイルの両方をサポートします。
次の例を参照してください。
次のコマンドを入力します。
$ SET COMMAND DCOM$LIBRARY:DCOM$GUIDGEN.CLD $ DCOM$GUIDGEN [/FORMAT=value] [/COUNT=value] [/OUTPUT=value]
次のコマンドを入力します。
$ mcr dcom$guidgen [-cdghirs?] [-on]
次の表はGUID形式オプションを示しています。
OpenVMS修飾子(value) | UNIX スイッチ | 使い方 |
---|---|---|
IDL | -i | GUIDをIDLインタフェース・ テンプレートに出力する。 |
STRUCT | -s | GUIDを初期化されたC 構造体として出力する。 |
IMPLEMENT_ OLECREATE | -c | GUID をIMPLEMENT_OLECREATE(...)形式で出力する。 |
DEFINE_GUID | -d | GUIDをDEFINE_GUID(...)形式で出力する。 |
GUID_STRUCT | -g | GUIDを初期化された静的const GUID構造体として出力する。 |
REGISTRY_GUID | -r
| GUIDをレジストリ形式で出力する。 |
Guidgen
ユーティリティの4つのオプションと同じです。
次の表は,DCOM$GUIDGEN
ユーティリティでサポートされる追加オプションを示しています。
OpenVMS修飾子 | UNIXスイッチ | 使い方 |
---|---|---|
/OUTPUT=filename | -
o filename | 出力を指定のファイルにリダイレクトする。 |
/COUNT=number | -n
number | 生成するGUIDの数を指定する。 |
not available | -h , -? | コマンド・ オプションの要約を表示する。 |
同じGUIDに対して複数の形式を指定できます。
この後の節では,MIDLコンパイラを使用してアプリケーションを構築する方法について説明します。
MIDLコンパイラは次のイメージで構成されています。
SYS$SYSTEM:DCOM$MIDL.EXE
DCLコマンド・ラインに指定された引数(パラメータ)を取り出す実行可能イメージ。
SYS$SHARE:DCOM$MIDL_SHR.EXE
DCOM$MIDL.EXE
の実際の作業を行う共用可能イメージ・
ライブラリ。
MIDLを実行するには,最初にDCLシンボルを定義しなければなりません。 次の例を参照してください。
$ midl :== $dcom$midl $ midl -? $ midl -Oicf -idcom$library: example.idl
midl -?
コマンドは,有効なコマンド・ライン引数の一覧を表示します。
これらの引数の一覧については,付録 A
を参照してください。
DCOM$MIDL.EXE
ユーティリティは,DCLフォーリン・コマンド・
ライン・バッファから引数を取得します。DCLフォーリン・コマンドでは最大255
文字を使用できます。
DCOM$MIDL.EXE
が受け付けることができる引数の数によっては,
複雑なMIDLコマンド(たとえば引用符が必要な大文字と小文字が混在した引数を含むコマンドなど)
を指定する場合は,この最大文字数を超えることがあります。
この問題を回避するには,SYS$SYSTEM:DCOM$RUNSHRLIB.EXE
ユーティリティを使用します。次の操作を行います。
DCOM$RUNSHRLIB
を定義します。
DCOM$RUNSHRLIB.EXE
を使用しなければならないプロセスは,
最初にOpenVMS DCL Command Definitionユーティリティを使用して,DCL
コマンドDCOM$RUNSHRLIB
を定義する必要があります。
次の例を参照してください。
$ SET COMMAND DCOM$LIBRARY:DCOM$RUNSHRLIB.CLD
DCOM$LIBRARY:DCOM$RUNSHRLIB.CLD
はDCOM$RUNSHRLIB
DCLコマンドを定義します。次の表はコマンドのパラメータを示しています。
引数 | 値 | 必須/省略可能 |
---|---|---|
P1 | 共用可能イメージ・
ライブラリの名前。論理名,
SYS$SHARE: 内のイメージの名前,完全なファイル指定のいずれかを指定できます。
| 必須 |
P2 | argc/argvベクタでCまたはC++ main()ルーチンとして呼び出されるルーチンの名前。 | 必須 |
P3 | 引用符で囲んだ修飾子の一覧。 | 省略可能 |
DCOM$RUNSHRLIB.EXE
を使用してコマンド・ラインを解析し,
DCOM$MIDL_SHR
共用可能イメージ・ライブラリ内の
DCOM$MIDL_MAIN
関数を呼び出すために,DCL
シンボルmidl
を定義します。次の例を参照してください。
$ midl :== DCOM$RUNSHRLIB DCOM$MIDL_SHR DCOM$MIDL_MAIN
新しいDCLコマンドMIDLは,1つの引用符で囲まれた文字列内の複数のコマンド・ ライン引数を受け付けます。コマンドが長すぎる場合は, 引用符で囲んだ複数の文字列を指定し,カンマで各文字列を区切ります。
たとえば,次の複雑なMIDLコマンドは,そのままでは使用できません。
$ midl :== $dcom$midl $ midl -Zp8 -Oicf -Os -oldnames -char unsigned - -error allocation -error bounds_check -error stub_data - -ms_ext -c_ext -out [.OBJ] - -I[INC] -I[PROJECT_WIDE_INC] -I[COMMON_INC] -IDCOM$LIBRARY: - -DRMS_DB "-DOpenVMS_Definitions" "-DPermanentProcess" - -header [.obj]example.h -client none -server none example.idl %DCL-W-TKNOVF, command element is too long - shorten
次のように,DCOM$RUNSHRLIB
を使用すると,このコマンドを正しく指定できます。
$ set command dcom$library:dcom$runshrlib.cld $ midl :== DCOM$RUNSHRLIB DCOM$MIDL_SHR DCOM$MIDL_MAIN $ midl "-Zp8 -Oicf -Os -oldnames -char unsigned",- "-error allocation -error bounds_check -error stub_data",- "-ms_ext -c_ext -out [.OBJ]",- "-I[INC] -I[PROJECT_WIDE_INC] -I[COMMON_INC] -IDCOM$LIBRARY:",- "-DRMS_DB -DOpenVMS_Definitions -DPermanentProcess",- "-header [.obj]example.h -client none -server none example.idl"
OpenVMSでMIDLを実行する場合,-Oicf
MIDLコマンド・ラインスイッチを指定しなければなりません。
MIDLコンポーネントは通常,UNKNWN.IDL
をインポートします。
これにはIUnknown
とIClassFactory
のコンポーネント定義が含まれています。
UNKNWN.IDL
と他のCOM
関連のIDLおよびヘッダ・ファイルは,DCOM$LIBRARY
にあります。
コンポーネントのIDLファイルを作成するには,次のスイッチを使用します。
-IDCOM$LIBRARY:
VMS_DCOM.H
ヘッダ・ファイルには,BristolのWind/U[R]
Win32環境でCOM for OpenVMSアプリケーションを正しくコンパイルするためのマクロ定義が含まれています。
このヘッダ・
ファイルは,自分で作成するファイルのうち,COM APIやWin32 API
に依存するすべてのソース・ファイルとヘッダ・ファイルに含まなければなりません。MIDL
で作成されるファイルはWin32環境に依存するので,
Compaqはすべての出力ファイルにVMS_DCOM.H
をインクルードするように,OpenVMS
用のMIDLコンパイラを変更しました。
ここでは,COM for OpenVMSアプリケーションのコンパイルの方法について説明します。
REG$LOOKUP
識別子があることを確認しなければなりません。コンパイル時または実行時にOpenVMS Registry
に対して
Readアクセス権とWriteアクセス権を必要とするアプリケーションの場合,
REG$UPDATE
識別子またはSYSPRV特権が必要です。OpenVMS Registry
に関連する特権の詳細については,
第7.5.1項を参照してください。
VMS_DCOM.H
ファイルでは,Wind/U Win32環境で使用される複数のマクロを定義しています。
このヘッダ・ファイルを指定するinclude
文は,作成するすべてのソース・ファイル(コードまたはヘッダ・
ファイル)のコメント以外の最初の行として指定しなければなりません。
しかし,MIDLで生成されるファイルの場合,この規則が必ずしも保証されません。
したがって,すべてのCコマンドとCXXコマンドに次の/DEFINE修飾子を必ず指定してください。
/DEFINE=(UNICODE=1,_WINDU_SOURCE=0X041000,_WIN32_DCOM)
UNICODE
マクロは,コードをコンパイルするときに,Win32
APIとデータ構造のワイド文字バージョンが有効に設定されているかどうか確認します(
このマクロはVMS_DCOM.H
にも定義されています)
。このマクロを省略すると,Wind/U Win32環境でコンパイル・エラーが発生することがあります。
他の2つのマクロ定義はWind/Uヘッダ・ファイルで認識され,構造とCOM APIの正しい定義を行うのに必要です。
COM for OpenVMSアプリケーションでは通常,
DCOM$LIBRARY
に格納されているヘッダ・ファイルが必要です。
次の修飾子をCおよびCXXコマンド・ラインに指定してください。
/INCLUDE=DCOM$LIBRARY
/INCLUDE
修飾子がコマンド・ラインにすでに指定されている場合は,
DCOM$LIBRARY
をインクルードするようにコマンドを変更してください。
VMS_DCOM.H
ヘッダ・ファイルでは,Wind/Uヘッダ・ファイルで使用される複数のマクロが定義されています。
このヘッダ・ファイルは,ソース・ファイル(ヘッダ・ファイルとインプリメンテーション・ ファイルの両方)にコメント以外の最初の行として指定しなければなりません。
COM for OpenVMSアプリケーションを作成する場合は, 次のC++修飾子を指定しなければなりません。
/EXCEPTIONS=CLEANUP
C++例外を有効にするために,C++コマンドに
/EXCEPTIONS=CLEANUP
修飾子を指定します。
/STANDARD=CFRONT
C++コンパイラでは多くのコンパイル標準規格がサポートされます。可能な限り
/STANDARD=CFRONT
を使用してください。
/STANDARD=CFRONT
は,AT&T[R] cfront実装に定義されている言語表記規則に従うように,
コンパイラに要求します。Wind/U
ヘッダ・ファイルはOpenVMSプラットフォームの他に,複数のUNIXプラットフォームでも使用されるため,
これらのヘッダ・ファイルに対してこのスイッチを使用すると便利です。
COM for OpenVMSアプリケーションを開発するときに指定しなければならないDEC C 固有の修飾子はありません。
COM for OpenVMSアプリケーションを作成するには, クライアント・イメージとコンポーネント・イメージの両方を作成しなければなりません。 コンポーネントは,プロセス内コンポーネントまたはプロセス外コンポーネントとして実装できるため, 共用可能イメージと実行可能イメージのどちらか一方, または両方を作成する必要があります。 新しいインタフェースを作成する場合は,プロキシ/スタブ共用可能イメージも作成しなければなりません。 プロキシ/スタブ共用可能イメージは, リモート・メソッド呼び出しの準備として,そのインタフェースのパラメータをパッケージするインタフェース固有のオブジェクトを提供します。 プロキシは送信側のアドレス空間で動作し,受信側のアドレス空間の対応するスタブと通信します。
ここでは,クライアント,コンポーネント,プロキシ/スタブ・イメージをリンクするときに必要な手順について説明します。
クライアント・イメージやコンポーネント実行可能イメージをリンクするために, 修飾子を指定する必要はありませんが,次のように2つのイメージをリンクしなければなりません。
リンク時に発生する依存関係は次のとおりです。
DCOM$WIN32:WINDU.OPT
DCOM$LIBRARY:DCOM.OPT
1つ以上のC++モジュールがある場合は,標準のOpenVMSリンカの代わりにC++ リンカ(CXXLINK)を使用して,C++リポジトリの場所を指定できるようにします(/CXX_REPOSITORY 修飾子)。次の例を参照してください。
$ CXXLINK/your-specific-linker-qualifiers list-of-object-modules, - _$ DCOM$WIN32:WINDU.OPT/OPTIONS, DCOM$LIBRARY:DCOM.OPT/OPTIONS - _$ application.OPT/OPTIONS /REPOSITORY=[.CXX_REPOSITORY]
オプション・ファイルは次の方法でもインクルードできます。
DCOM$LIBRARY:DCOM.OPT
を使用する方法。
プロセス内コンポーネント共用可能イメージの依存関係の一覧は,クライアント・ イメージやコンポーネント実行可能イメージとは少し異なります。 リンク時に発生する特定の依存関係は次のとおりです。
DCOM$WIN32:WINDU.OPT
DCOM$LIBRARY:DCOM.OPT
プロセス内コンポーネント共用可能イメージをリンクするには,COM for OpenVMS
が共用可能イメージ内で呼び出すエントリ・
ポイントのシンボル・ベクタを作成しなければなりません。Win32
実行時環境では,DllMain
エントリ・ポイントに対して標準命名規則が適用されます。
次の要素を含まなければなりません。
_Windu_
接頭辞
イメージ名が$SHR
で終わる場合(たとえば,
CMPNT$SHR
)の場合,接尾辞はドル記号($)も含むイメージ名です。
イメージ名が$SHR
以外で終了する場合(たとえば,
CMPNT_SHARE
),接尾辞は完全なイメージ名です。
たとえば,CMPNT$SHR
という名前のコンポーネント共用可能イメージは,
次のオプション・ファイルを使用してシンボル・ベクタを定義します。
! ! The list of symbols exported by CMPNT$SHR.EXE. ! SYMBOL_VECTOR=(- _WindU_DllMain_CMPNT$/DllMain = PROCEDURE,- DllGetClassObject = PROCEDURE,- DllCanUnloadNow = PROCEDURE,- DllRegisterServer = PROCEDURE,- DllUnregisterServer = PROCEDURE)
CMPNT_SHARE
という名前のコンポーネント共用可能イメージは,
次のオプション・ファイルを使用してシンボル・ベクタを定義します。
! ! The list of symbols exported by CMPNT_SHARE.EXE. ! SYMBOL_VECTOR=(- _WindU_DllMain_CMPNT_SHARE/DllMain = PROCEDURE,- DllGetClassObject = PROCEDURE,- DllCanUnloadNow = PROCEDURE,- DllRegisterServer = PROCEDURE,- DllUnregisterServer = PROCEDURE)
プロキシ/スタブ共用可能イメージの依存関係の一覧は,クライアントおよびコンポーネント実行可能イメージの依存関係とは少し異なります。 リンク時に発生する特定の依存関係は次のとおりです。
DCOM$WIN32:WINDU.OPT
SYS$LIBRARY:DCOM$RPCRT4_SHR.EXE
プロキシ/スタブ共用可能イメージのリンクでは,COM for OpenVMSが共用可能イメージ内で呼び出すエントリ・
ポイントのシンボル・ベクタを作成しなければならないので,もう少し複雑になります。Win32
実行時環境では,DllMain
エントリ・
ポイントに対して標準の命名規則を適用しています。次の要素を含まなければなりません。
_Windu_
接頭辞
イメージ名が$SHR
で終わる場合(たとえば,
PROXY$SHR
),接尾辞はドル記号($)を含むイメージ名です。
イメージ名が$SHR
以外で終わる場合(たとえば,
PROXY_SHARE
),接尾辞は完全なイメージ名てす。
たとえば,PROXY$SHR
という名前のプロキシ/スタブ共用可能イメージは,
次のオプション・ファイルを使用してシンボル・ベクタを定義します。
! ! RPC Shareable Image ! SYS$LIBRARY:DCOM$RPCRT4_SHR.EXE/SHARE ! ! ! The list of symbols exported by PROXY$SHR.EXE. ! SYMBOL_VECTOR=(- _Windu_DllMain_PROXY$/DllMain = PROCEDURE,- DllGetClassObject = PROCEDURE,- DllCanUnloadNow = PROCEDURE,- GetProxyDllInfo = PROCEDURE,- DllRegisterServer = PROCEDURE,- DllUnregisterServer = PROCEDURE)
PROXY_SHARE
という名前のプロキシ/スタブ共用可能イメージは,
次のオプション・ファイルを使用してシンボル・ベクタを定義します。
! ! RPC Shareable Image ! SYS$LIBRARY:DCOM$RPCRT4_SHR.EXE/SHARE ! ! ! The list of symbols exported by PROXY_SHARE.EXE. ! SYMBOL_VECTOR=(- _Windu_DllMain_PROXY_SHARE/DllMain = PROCEDURE,- DllGetClassObject = PROCEDURE,- DllCanUnloadNow = PROCEDURE,- GetProxyDllInfo = PROCEDURE,- DllRegisterServer = PROCEDURE,- DllUnregisterServer = PROCEDURE)
この後の節では,必要なOpenVMS Registryエントリについて説明します。
CLSIDサブキーには,システムでサポートされるコンポーネントのすべてのCLSID が含まれます。コンポーネントのCLSIDはここに登録しなければなりません。 登録する各CLSIDには,次の要素を含まなければなりません。
AppID
という名前付き値。最後が0の文字列あり,
コンポーネントのCLSIDを表すデータ値です。
クラス識別子(CLSID)は,OLEクラス・オブジェクトに関連付けられたグローバル一意識別子(GUID) です。COM for OpenVMSサーバ・アプリケーションは通常,CLSIDをOpenVMS Registryに登録することで, クライアントがOLEクラス・ オブジェクトに関連付けられた実行可能コードを検索して,ロードできるようにしています。
コンポーネントのCLSIDはHKEY_CLASSES_ROOT\CLSID
というサブキーに登録します。
コンポーネントCLSIDの登録には,次のサブキーを含まなければなりません。
LocalServer32
このキーの値は最後が0の文字列であり,プロセス外サーバ実行可能イメージの場所を表すデータ値です。
ProgID
このキーの値は最後が0の文字列であり,CLSIDのプログラムIDを表すデータ値です。 通常,program.component.versionという形式です。
VersionIndependentProgID
このキーの値は最後が0の文字列であり,CLSIDのプログラムID ( バージョン番号を除くID)を表すデータ値です。通常, program.componentという形式です。
InProcServer32
このキーの値は最後が0の文字列であり,プロセス内サーバ共用可能イメージの場所を表すデータ値です。
Type Libraries
タイプ・ライブラリは,IDispatch
インタフェースを実装するときに重要です。
タイプ・ライブラリは,OLEオートメーション
RegisterTypeLib
実行時ルーチンを呼び出すときに,
それ自体を登録します。Typelib
サブキーをコンポーネントのCLSID
の下に追加しなければなりません。Typelib
サブキーには,タイプ・ライブラリのGUIDが含まれます。たとえば,
次のキーにはLIBIDを含まなければなりません。
HKEY_CLASSES_ROOT\CLSID\{GUID}\TYPELIB {value=LIBID}
プロキシ/スタブ共用可能イメージは,インタフェースのパラメータをパッケージするためにインタフェース固有のオブジェクトを提供します。 プロキシ/ スタブ共用可能イメージにはオブジェクトが含まれるので,CLSID が必要であり,OpenVMS Registryに登録しなければなりません。 プロキシのCLSIDは,コンポーネントのCLSIDと同じ方法でOpenVMS Registry に登録する必要があります。
プロキシのCLSIDはHKEY_CLASSES_ROOT\CLSID
というサブキーに登録しなければなりません。
プロキシ/スタブCLSIDの登録には,次のサブキーを含まなければなりません。
InProcServer32
InProcServer32
の値は最後が0の文字列であり,プロキシ/
スタブ共用可能イメージの場所を表すデータ値です。プロキシ/スタブCLSID
とそのサブキーを使用して,COMはプロキシ/スタブ共用可能イメージを検索することができます。
Interface
サブキーには,システムに登録されているすべてのインタフェースが含まれます。
コンポーネントのインタフェースID
(IID)をこのサブキーに登録しなければなりません。
登録される各インタフェースには,少なくとも次のいずれかのサブキーが含まれます。
NumMethods
NumMethods
の値は最後が0の文字列であり,これはインタフェースに含まれるメソッドの数を表すデータ値です。
ProxyStubClsid32
ProxyStubClsid32
の値は最後が0の文字列であり,これはプロキシ/
スタブ共用可能イメージのCLSIDを表すデータ値です。このCLSID
は,第6.5.1.2項で説明したものと同じでなければなりません。
COMコンポーネントを開発し,テストする場合,OpenVMSシステムとWindows NT システムから判読できないエラー・コードが返されることがあります。 これらのコードをもっとわかりやすくするのに役立つように,Compaq はエラー・コードを表示可能なテキストに変換するためのNTA$VMSGetMessage ルーチンを提供しています。
このルーチンを実装するには,NTA_MESSAGE.HファイルをDCOM$LIBRARY:
ディレクトリにインクルードし,DCOM$LIBRARY:NTA_
GETMSG.OBJ
オブジェクト・モジュールとリンクしなければなりません。
この節では,NTA$VMSGetMessageルーチンについて説明します。
NTA$VMSGetMessageルーチンはエラー・コードを表示可能なテキストに変換します。 入力エラー・コードは次のいずれかでなければなりません。
Return=NTA$VMSGetMessage (status, text, flag, [count])
入力エラー・コード | 例 |
---|---|
OpenVMSエラー・コード | 0x074AA6BA |
Windows HRESULT | 0x80070031 |
Windows Win32 エラー・コード | 0x00000031 |
Windows NTユーザ定義ビットがセットされた状態コード | 0xE74AA6BA |
セキュリティAPIがWindows NT状態コードを返す場合は, 状態フィールドの形式はOpenVMS状態コードとWindows NT状態コントロール・ ビット・セットのORです。次の例を参照してください。
入力エラー・コード | 結果 |
---|---|
OpenVMSエラー・コード | 0x074AA6BA |
Windows NT状態コード | 0xE74AA6BA |
NTAWIN$_UNKNOWN | 不明のエラー・コード |
NTAWIN$_VMS | OpenVMSエラー・ コード |
NTAWIN$_NT | Windows HRESULTエラー・コード |
NTAWIN$_WINDOWS | Windows Win32エラー・コード |
NTAWIN$_USER | Windows NT状態コード |
NTAWIN$_UNKNOWNという値を指定した場合は,できるだけ正しいテキストを作成できるように, 最適な見積もりが行われます。ルーチンはテキストを次のように解析します。
OpenVMSエラー・コードとWindows Win32エラー・コードの区別はできません。
このルーチンを呼び出すには,NTA_MESSAGE.HファイルをDCOM$LIBRARY:ディレクトリにインクルードし,SYS$LIBRARY:DCOM$WIN32_SHR 共用可能イメージとリンクしなければなりません。
[ 前のページ ]
[ 次のページ ]
[ 目次 ]
[ 索引 ]
[ DOC Home ]