Delphi5 で COM+ コンポーネントを作成する場合、ObjectContext を常に取得できるわけではありません
つまり、GetObjectContext を呼び出すと nil が返され、トランザクションが正しく処理されなくなります。
インターネットで、COM+ コンポーネントの前に行を追加して mtxex.dll をロードするようにと誰かが教えてくれました。
この問題は解決されますが、動作が不安定なようです。
プロシージャ TgEntityObj.Initialize;
始める
継承された。
LoadLibrary('mtxex.dll');
終わり;
ただし、このステートメントを追加しなくても、Delphi6 では ObjectContext を取得できます。
D6 の MTX ユニットが D5 とは実際に異なることがわかりました。これについてはボーランドを責めることはできません。
D5が出た当時はまだWIN2000(COM+)が出ていなかったので、D5のMTXユニットはまだ積まれていました。
MTSの書き方。
D5 MTXユニットの253行目。
実装
ComObj を使用します。
タイプ
TGetObjectContextProc = 関数(var ObjectContext: IObjectContext): HRESULT;
TSafeRefProc = 関数(const riding: TGUID; Unk: IUnknown): ポインタ;
変数
GetObjectContextProc: TGetObjectContextProc = nil;
SafeRefProc: TSafeRefProc = nil;
MtsProcsLoaded: ブール値 = False;
プロシージャ LoadMtsProcs;
変数
Mtxdll: HModule;
始める
MtsProcsLoaded の場合は終了します。
MtsProcsLoaded := True;
Mtxdll := GetModuleHandle('mtxex.dll');
mtxdll <> 0 の場合
始める
@GetObjectContextProc := GetProcAddress(Mtxdll, 'GetObjectContext');
@SafeRefProc := GetProcAddress(Mtxdll, 'SafeRef');
終わり;
終わり;
関数 GetObjectContext: IObjectContext;
始める
LoadMtsProcs;
割り当て済み(GetObjectContextProc)の場合、
OleCheck(GetObjectContextProc(結果))
それ以外
Result := nil; //単一ステップを実行する場合は null を返します。
終わり;
D6のMTXユニットが異なりますのでご注意ください。
実装
ComObj を使用します。
タイプ
TGetObjectContextProc = 関数(var ObjectContext: IObjectContext): HRESULT;
///
TCoGetObjectContextProc = function(const riid: TGUID; var ObjectContext: IObjectContext): HRESULT;
TSafeRefProc = 関数(const riding: TGUID; Unk: IUnknown): ポインタ;
変数
GetObjectContextProc: TGetObjectContextProc = nil;
CoGetObjectContextProc: TCoGetObjectContextProc = nil;
SafeRefProc: TSafeRefProc = nil;
MtsProcsLoaded: ブール値 = False;
function IsComPlusPlatform: boolean; ////// COM+ かどうか。
変数
Ver: TOsVersionInfo;////
始める
Ver.dwOSVersionInfoSize := sizeof(Ver);////
GetVersionEx(Ver);
if (Ver.dwPlatformID = VER_PLATFORM_WIN32_NT) and///
(Ver.dwMajorVersion >= 5) then////
結果 := true //
それ以外の場合、結果 := false;
終わり; //////
プロシージャ LoadMtsProcs;
変数
Mtxdll: HModule;
始める
MtsProcsLoaded の場合は終了します。
MtsProcsLoaded := True;
IsComPlusPlatform の場合 ////
始める
Mtxdll := GetModuleHandle('ole32.dll'); ///
if mtxdll <> 0 then ///
@CoGetObjectContextProc := GetProcAddress(Mtxdll, 'CoGetObjectContext');
終わり ///
それ以外
始める
Mtxdll := GetModuleHandle('mtxex.dll');
mtxdll <> 0 の場合
始める
@GetObjectContextProc := GetProcAddress(Mtxdll, 'GetObjectContext');
@SafeRefProc := GetProcAddress(Mtxdll, 'SafeRef');
終わり;
終わり;
終わり;
関数 GetObjectContext: IObjectContext;
定数
IID_IObjectContext: TGUID = '{51372AE0-CAE7-11CF-BE81-00AA00A2FA25}'; ///
始める
LoadMtsProcs;
if Assigned(CoGetObjectContextProc) then ///
CoGetObjectContextProc(IID_IObjectContext, Result) ///
それ以外の場合、Assigned(GetObjectContextProc) の場合
OleCheck(GetObjectContextProc(結果))
それ以外
結果 := nil;
終わり;
斜めに細くなった部分が多くなります。これらの部分に D5 MTX を追加し、プログラムのカレント ディレクトリに保存するだけです。
プログラムをコンパイルして ObjectContext を取得します。