When writing COM+ components in Delphi5, the ObjectContext cannot always be obtained
That is, calling GetObjectContext returns nil. This prevents transaction processing from being correct.
Done. Someone told me on the Internet to add a line before the COM+ component to load mtxex.dll
statement. It does solve this problem, but it seems to run unstable.
PRocedure TgEntityObj.Initialize;
begin
inherited;
LoadLibrary('mtxex.dll');
end;
But I can get the ObjectContext in Delphi6 without adding this statement.
I saw that the MTX unit in the D6 is indeed different from the D5. I can’t blame Borland for this.
When D5 came out, WIN2000 (COM+) had not yet come out, so the MTX unit in D5 was still loaded.
How to write MTS.
Line 253 in D5 MTX unit.
implementation
usesComObj;
type
TGetObjectContextProc = function(var ObjectContext: IObjectContext): HRESULT; cdecl;
TSafeRefProc = function(const rid: TGUID; Unk: IUnknown): Pointer; cdecl;
var
GetObjectContextProc: TGetObjectContextProc = nil;
SafeRefProc: TSafeRefProc = nil;
MtsProcsLoaded: Boolean = False;
procedure LoadMtsProcs;
var
Mtxdll: HModule;
begin
if MtsProcsLoaded then Exit;
MtsProcsLoaded := True;
Mtxdll := GetModuleHandle('mtxex.dll');
if mtxdll <> 0 then
begin
@GetObjectContextProc := GetProcAddress(Mtxdll, 'GetObjectContext');
@SafeRefProc := GetProcAddress(Mtxdll, 'SafeRef');
end;
end;
function GetObjectContext: IObjectContext;
begin
LoadMtsProcs;
if Assigned(GetObjectContextProc) then
OleCheck(GetObjectContextProc(Result))
else
Result := nil; //Returns null when executing single step.
end;
Note that the MTX unit in D6 is different.
implementation
usesComObj;
type
TGetObjectContextProc = function(var ObjectContext: IObjectContext): HRESULT; cdecl;
///
TCoGetObjectContextProc = function(const riid: TGUID; var ObjectContext: IObjectContext): HRESULT; stdcall;
TSafeRefProc = function(const rid: TGUID; Unk: IUnknown): Pointer; cdecl;
var
GetObjectContextProc: TGetObjectContextProc = nil;
CoGetObjectContextProc: TCoGetObjectContextProc = nil; ///
SafeRefProc: TSafeRefProc = nil;
MtsProcsLoaded: Boolean = False;
function IsComPlusPlatform: boolean; ////// Whether it is COM+
var
Ver: TOsVersionInfo;////
begin
Ver.dwOSVersionInfoSize := sizeof(Ver);////
GetVersionEx(Ver);
if (Ver.dwPlatformID = VER_PLATFORM_WIN32_NT) and///
(Ver.dwMajorVersion >= 5) then////
Result := true //
else Result := false;
end; //////
procedure LoadMtsProcs;
var
Mtxdll: HModule;
begin
if MtsProcsLoaded then Exit;
MtsProcsLoaded := True;
if IsComPlusPlatform then ////
begin
Mtxdll := GetModuleHandle('ole32.dll'); ///
if mtxdll <> 0 then ///
@CoGetObjectContextProc := GetProcAddress(Mtxdll, 'CoGetObjectContext');
end ///
else
begin
Mtxdll := GetModuleHandle('mtxex.dll');
if mtxdll <> 0 then
begin
@GetObjectContextProc := GetProcAddress(Mtxdll, 'GetObjectContext');
@SafeRefProc := GetProcAddress(Mtxdll, 'SafeRef');
end;
end;
end;
function GetObjectContext: IObjectContext;
const
IID_IObjectContext: TGUID = '{51372AE0-CAE7-11CF-BE81-00AA00A2FA25}'; ///
begin
LoadMtsProcs;
if Assigned(CoGetObjectContextProc) then ///
CoGetObjectContextProc(IID_IObjectContext, Result) ///
else if Assigned(GetObjectContextProc) then
OleCheck(GetObjectContextProc(Result))
else
Result := nil;
end;
The diagonally thinned parts are the many parts. You only need to add D5 MTX to these parts. Then save it to the current directory of your program.
Compile the program to obtain the ObjectContext.