[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]

6 COM for OpenVMSアプリケーションの開発

この章では,OpenVMS用のCOMアプリケーションの開発方法について説明します。


注意
この章で使用するサンプルのCOM アプリケーションは,COM for OpenVMSキットの次のディレクトリにあります。
     DCOM$EXAMPLES:[SAMPLE1]
     DCOM$EXAMPLES:[SIMPLE]
     DCOM$EXAMPLES:[DISPATCH_SAMPLE1]
SAMPLE1DISPATCH_SAMPLE1 は,Microsoft Pressから出版されているDale Rogerson著『Inside COM』という書籍からの抜粋です。 この書籍はCOMアプリケーションを開発する際に非常に役立つ参考文献です。

ここでは,COM for OpenVMSアプリケーションの作成方法について説明します。


注意
COM for OpenVMSアプリケーションを開発する場合,プロセスの仮想メモリが必要です。COM for OpenVMS アプリケーションを作成する前に, 少なくとも100,000ページレットのページ・ファイル・ クォータがあることを確認してください。これはDEC C++コンパイラの要件です。

6.1 ステップ 1:一意識別子を生成する

16バイトのグローバル一意識別子(GUID)を生成するには, DCOM$GUIDGEN ユーティリティを使用します。このユーティリティはOpenVMS スタイルとUNIXスタイルの両方をサポートします。 次の例を参照してください。

次の表は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をレジストリ形式で出力する。


注意
この表の最後の4つのオプションは,Windows NT のGuidgen ユーティリティの4つのオプションと同じです。

次の表は,DCOM$GUIDGEN ユーティリティでサポートされる追加オプションを示しています。

OpenVMS修飾子 UNIXスイッチ 使い方
/OUTPUT=filename - o filename 出力を指定のファイルにリダイレクトする。
/COUNT=number -n number 生成するGUIDの数を指定する。
not available -h , -? コマンド・ オプションの要約を表示する。

同じGUIDに対して複数の形式を指定できます。

6.2 ステップ 2: MIDLコンパイラを使用してアプリケーションを構築する

この後の節では,MIDLコンパイラを使用してアプリケーションを構築する方法について説明します。

6.2.1 MIDLコンパイラの実行

MIDLコンパイラは次のイメージで構成されています。

MIDLを実行するには,最初にDCLシンボルを定義しなければなりません。 次の例を参照してください。

         $ midl :== $dcom$midl
         $ midl -?
         $ midl -Oicf -idcom$library: example.idl

midl -? コマンドは,有効なコマンド・ライン引数の一覧を表示します。 これらの引数の一覧については,付録 A を参照してください。

6.2.2 DCOM$RUNSHRLIBによるMIDLコンパイラの実行

DCOM$MIDL.EXE ユーティリティは,DCLフォーリン・コマンド・ ライン・バッファから引数を取得します。DCLフォーリン・コマンドでは最大255 文字を使用できます。

DCOM$MIDL.EXE が受け付けることができる引数の数によっては, 複雑なMIDLコマンド(たとえば引用符が必要な大文字と小文字が混在した引数を含むコマンドなど) を指定する場合は,この最大文字数を超えることがあります。

この問題を回避するには,SYS$SYSTEM:DCOM$RUNSHRLIB.EXE ユーティリティを使用します。次の操作を行います。

  1. DCLコマンドDCOM$RUNSHRLIB を定義します。

    DCOM$RUNSHRLIB.EXE を使用しなければならないプロセスは, 最初にOpenVMS DCL Command Definitionユーティリティを使用して,DCL コマンドDCOM$RUNSHRLIB を定義する必要があります。 次の例を参照してください。

           $ SET COMMAND DCOM$LIBRARY:DCOM$RUNSHRLIB.CLD
    

    DCOM$LIBRARY:DCOM$RUNSHRLIB.CLDDCOM$RUNSHRLIB DCLコマンドを定義します。次の表はコマンドのパラメータを示しています。

    引数 必須/省略可能
    P1 共用可能イメージ・ ライブラリの名前。論理名, SYS$SHARE: 内のイメージの名前,完全なファイル指定のいずれかを指定できます。 必須
    P2 argc/argvベクタでCまたはC++ main()ルーチンとして呼び出されるルーチンの名前。 必須
    P3 引用符で囲んだ修飾子の一覧。 省略可能

  2. 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"
    

6.2.3 必須MIDLスイッチ

OpenVMSでMIDLを実行する場合,-Oicf MIDLコマンド・ラインスイッチを指定しなければなりません。

6.2.4 必須インクルード・ディレクトリ

MIDLコンポーネントは通常,UNKNWN.IDL をインポートします。 これにはIUnknownIClassFactory のコンポーネント定義が含まれています。 UNKNWN.IDL と他のCOM 関連のIDLおよびヘッダ・ファイルは,DCOM$LIBRARY にあります。 コンポーネントのIDLファイルを作成するには,次のスイッチを使用します。

     -IDCOM$LIBRARY:

6.2.5 必須ヘッダ・ファイル

VMS_DCOM.H ヘッダ・ファイルには,BristolのWind/U[R] Win32環境でCOM for OpenVMSアプリケーションを正しくコンパイルするためのマクロ定義が含まれています。 このヘッダ・ ファイルは,自分で作成するファイルのうち,COM APIやWin32 API に依存するすべてのソース・ファイルとヘッダ・ファイルに含まなければなりません。MIDL で作成されるファイルはWin32環境に依存するので, Compaqはすべての出力ファイルにVMS_DCOM.H をインクルードするように,OpenVMS 用のMIDLコンパイラを変更しました。

6.3 ステップ 3: COMアプリケーションをコンパイルする

ここでは,COM for OpenVMSアプリケーションのコンパイルの方法について説明します。


注意
OpenVMS Registryに対するReadアクセス権を必要とするCOM アプリケーションを開発する場合は,REG$LOOKUP 識別子があることを確認しなければなりません。コンパイル時または実行時にOpenVMS Registry に対して Readアクセス権とWriteアクセス権を必要とするアプリケーションの場合, REG$UPDATE 識別子またはSYSPRV特権が必要です。OpenVMS Registry に関連する特権の詳細については, 第7.5.1項を参照してください。

6.3.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の正しい定義を行うのに必要です。

6.3.2 必要なインクルード・ディレクトリ

COM for OpenVMSアプリケーションでは通常, DCOM$LIBRARY に格納されているヘッダ・ファイルが必要です。

次の修飾子をCおよびCXXコマンド・ラインに指定してください。

     /INCLUDE=DCOM$LIBRARY

/INCLUDE 修飾子がコマンド・ラインにすでに指定されている場合は, DCOM$LIBRARY をインクルードするようにコマンドを変更してください。

6.3.3 必要なヘッダ・ファイル: VMS_DCOM.H

VMS_DCOM.H ヘッダ・ファイルでは,Wind/Uヘッダ・ファイルで使用される複数のマクロが定義されています。

このヘッダ・ファイルは,ソース・ファイル(ヘッダ・ファイルとインプリメンテーション・ ファイルの両方)にコメント以外の最初の行として指定しなければなりません。

6.3.4 必要なC++修飾子

COM for OpenVMSアプリケーションを作成する場合は, 次のC++修飾子を指定しなければなりません。

6.3.5 必要なC修飾子

COM for OpenVMSアプリケーションを開発するときに指定しなければならないDEC C 固有の修飾子はありません。

6.4 ステップ 4: COMアプリケーションをリンクする

COM for OpenVMSアプリケーションを作成するには, クライアント・イメージとコンポーネント・イメージの両方を作成しなければなりません。 コンポーネントは,プロセス内コンポーネントまたはプロセス外コンポーネントとして実装できるため, 共用可能イメージと実行可能イメージのどちらか一方, または両方を作成する必要があります。 新しいインタフェースを作成する場合は,プロキシ/スタブ共用可能イメージも作成しなければなりません。 プロキシ/スタブ共用可能イメージは, リモート・メソッド呼び出しの準備として,そのインタフェースのパラメータをパッケージするインタフェース固有のオブジェクトを提供します。 プロキシは送信側のアドレス空間で動作し,受信側のアドレス空間の対応するスタブと通信します。

ここでは,クライアント,コンポーネント,プロキシ/スタブ・イメージをリンクするときに必要な手順について説明します。

6.4.1 クライアントとプロセス外コンポーネントのリンク

クライアント・イメージやコンポーネント実行可能イメージをリンクするために, 修飾子を指定する必要はありませんが,次のように2つのイメージをリンクしなければなりません。

リンク時に発生する依存関係は次のとおりです。

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]

オプション・ファイルは次の方法でもインクルードできます。

6.4.2 プロセス内コンポーネント共用可能イメージのリンク

プロセス内コンポーネント共用可能イメージの依存関係の一覧は,クライアント・ イメージやコンポーネント実行可能イメージとは少し異なります。 リンク時に発生する特定の依存関係は次のとおりです。

6.4.2.1 シンボル・ベクタの作成

プロセス内コンポーネント共用可能イメージをリンクするには,COM for OpenVMS が共用可能イメージ内で呼び出すエントリ・ ポイントのシンボル・ベクタを作成しなければなりません。Win32 実行時環境では,DllMain エントリ・ポイントに対して標準命名規則が適用されます。 次の要素を含まなければなりません。

たとえば,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)

6.4.3 プロキシ/スタブ共用可能イメージのリンク

プロキシ/スタブ共用可能イメージの依存関係の一覧は,クライアントおよびコンポーネント実行可能イメージの依存関係とは少し異なります。 リンク時に発生する特定の依存関係は次のとおりです。

6.4.3.1 シンボル・ベクタの作成

プロキシ/スタブ共用可能イメージのリンクでは,COM for OpenVMSが共用可能イメージ内で呼び出すエントリ・ ポイントのシンボル・ベクタを作成しなければならないので,もう少し複雑になります。Win32 実行時環境では,DllMain エントリ・ ポイントに対して標準の命名規則を適用しています。次の要素を含まなければなりません。

たとえば,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)

6.5 必要なOpenVMS Registryエントリ

この後の節では,必要なOpenVMS Registryエントリについて説明します。

6.5.1 HKEY_CLASSES_ROOT\CLSID

CLSIDサブキーには,システムでサポートされるコンポーネントのすべてのCLSID が含まれます。コンポーネントのCLSIDはここに登録しなければなりません。 登録する各CLSIDには,次の要素を含まなければなりません。

6.5.1.1 コンポーネントCLSID

クラス識別子(CLSID)は,OLEクラス・オブジェクトに関連付けられたグローバル一意識別子(GUID) です。COM for OpenVMSサーバ・アプリケーションは通常,CLSIDをOpenVMS Registryに登録することで, クライアントがOLEクラス・ オブジェクトに関連付けられた実行可能コードを検索して,ロードできるようにしています。

コンポーネントのCLSIDはHKEY_CLASSES_ROOT\CLSID というサブキーに登録します。

コンポーネントCLSIDの登録には,次のサブキーを含まなければなりません。

6.5.1.2 プロキシ/スタブCLSID

プロキシ/スタブ共用可能イメージは,インタフェースのパラメータをパッケージするためにインタフェース固有のオブジェクトを提供します。 プロキシ/ スタブ共用可能イメージにはオブジェクトが含まれるので,CLSID が必要であり,OpenVMS Registryに登録しなければなりません。 プロキシのCLSIDは,コンポーネントのCLSIDと同じ方法でOpenVMS Registry に登録する必要があります。

プロキシのCLSIDはHKEY_CLASSES_ROOT\CLSID というサブキーに登録しなければなりません。

プロキシ/スタブCLSIDの登録には,次のサブキーを含まなければなりません。

6.5.2 HKEY_CLASSES_ROOT\インタフェース

Interface サブキーには,システムに登録されているすべてのインタフェースが含まれます。 コンポーネントのインタフェースID (IID)をこのサブキーに登録しなければなりません。

登録される各インタフェースには,少なくとも次のいずれかのサブキーが含まれます。

6.6 OpenVMSおよびWindowsのエラー・ コードのテキストへの変換

COMコンポーネントを開発し,テストする場合,OpenVMSシステムとWindows NT システムから判読できないエラー・コードが返されることがあります。 これらのコードをもっとわかりやすくするのに役立つように,Compaq はエラー・コードを表示可能なテキストに変換するためのNTA$VMSGetMessage ルーチンを提供しています。

このルーチンを実装するには,NTA_MESSAGE.HファイルをDCOM$LIBRARY: ディレクトリにインクルードし,DCOM$LIBRARY:NTA_ GETMSG.OBJ オブジェクト・モジュールとリンクしなければなりません。

この節では,NTA$VMSGetMessageルーチンについて説明します。

NTA$VMSGetMessage

NTA$VMSGetMessageルーチンはエラー・コードを表示可能なテキストに変換します。 入力エラー・コードは次のいずれかでなければなりません。

フォーマット

     Return=NTA$VMSGetMessage   (status, text, flag, [count])

引数

status OpenVMS使用法: error_code タイプ: longword (unsigned) アクセス: read only メカニズム: by value
この状態フィールドは次のいずれかでなければなりません。

入力エラー・コード
OpenVMSエラー・コード 0x074AA6BA
Windows HRESULT 0x80070031
Windows Win32 エラー・コード 0x00000031
Windows NTユーザ定義ビットがセットされた状態コード 0xE74AA6BA

セキュリティAPIがWindows NT状態コードを返す場合は, 状態フィールドの形式はOpenVMS状態コードとWindows NT状態コントロール・ ビット・セットのORです。次の例を参照してください。

入力エラー・コード 結果
OpenVMSエラー・コード 0x074AA6BA
Windows NT状態コード 0xE74AA6BA

text OpenVMS使用法: error_text タイプ: character string アクセス: write メカニズム: by reference
この引数は最後がNULLの文字列であり,SYS$GETMSGシステム・サービスから返されたテキストが含まれます。 返される最大サイズ(SYS$GETMSGシステム・ サービスで定義されているサイズ)は256バイトです。メモリが上書きされないようにするために, 呼び出し側は少なくとも257バイトのバッファ・アドレスを提供しなければなりません。
flag OpenVMS使用法: flag タイプ: longword (unsigned) アクセス: read only メカニズム: by value
エラー・コードの変換を制御します。次の値はNTA_MESSAGE.Hに定義されています。

NTAWIN$_UNKNOWN 不明のエラー・コード
NTAWIN$_VMS OpenVMSエラー・ コード
NTAWIN$_NT Windows HRESULTエラー・コード
NTAWIN$_WINDOWS Windows Win32エラー・コード
NTAWIN$_USER Windows NT状態コード

NTAWIN$_UNKNOWNという値を指定した場合は,できるだけ正しいテキストを作成できるように, 最適な見積もりが行われます。ルーチンはテキストを次のように解析します。

  1. まず,Windows HRESULTであるかどうか確認します(上位ニブル= 0x8) 。Windows HRESULTでない場合は,次のステップに進みます。

  2. 次に,Windows NTのユーザ定義状態コードであるかどうか確認します( 上位ニブル= 0xE)。この条件が満たされない場合は, 次のステップに進みます。

  3. これはOpenVMSエラー・コードであると判断されます。

    OpenVMSエラー・コードとWindows Win32エラー・コードの区別はできません。

count OpenVMS使用法: FAO count タイプ: longword (unsigned) アクセス: write メカニズム: by reference
この引数は,戻りメッセージに任意に返されるFAO引数の数です。現在, すべてのNTAWINメッセージでASCII置換引数(!AS)だけが使用されています。 呼び出し側はSYS$FAOで置換する前に,すべての数値データをASCIIに変換しなければなりません。
説明このルーチンはOpenVMS SYS$GETMSG システム・サービスを使用します。 メッセージはSYS$MESSAGE:NTAWINMSG.EXEイメージとSYS$MESSAGE:NTARPCMSG.EXE イメージに格納されます。

このルーチンを呼び出すには,NTA_MESSAGE.HファイルをDCOM$LIBRARY:ディレクトリにインクルードし,SYS$LIBRARY:DCOM$WIN32_SHR 共用可能イメージとリンクしなければなりません。

返される条件値


SYS$GETMSGシステム・サービスからの状態

SYS$GETMSGシステム・サービスの詳細については,『OpenVMS System Services Reference Manual』を参照してください。


[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]