Home > How-To > Fix Corba DII bug in Delphi 6

Created Nov 25, 2001
Last update Nov 25, 2001
Product D6
Versions Delphi 6, Delhi 6 Update Pack 1
Corba ORB Visibroker 3.3 for C++
 
Problem Using Delphi 6 and Corba DII results in corruption of any parameter passed from client to server.  For example Corba server has a method: void AddInt(in long Int1, in long Int2);
If client calls this method with Int1 = 2, Int2 = 5 server gets absolutely wrong values.  Values can be random or not but they are not valid in any case.  This problem has been verified with any parameter passed  to the client.
 
Inside info In Corba world DII stands for Dynamic Interface Invocation.  Just think about it as late-bound IDispatch call in COM. The simplified way to think how Delphi 6 invokes Corba server is this:  Delphi client loads DII marshalling DLL orbpas60.dll.  This DLL searches Corba Interface repository for interface definition, constructs the call and invokes Corba server.  To understand details of DII invocation you can trace procedure _DispInvoke in variants.pas.  The problem is this: Delphi 5 used to pass Params as pointer but D6 passes the address of Params instead.  Take a look at VarDispProc call inside of _DispInvoke. 
 
File to fix CorbaObj.pas  There are two places to put fixes in. You can download fixed file here.
 
Place #1 procedure CorbaObjectDispatch (Result: PVariant; const Instance: Variant; CallDesc: PCallDesc; Params: Pointer); cdecl;
var
  U: IUnknown;
  StubObject: IStubObject;
  Stub: IStub;
  R: Integer;
  ProcResult: Variant;
begin
  if Result = nil then Result := @ProcResult;
  U := IUnknown(Instance);
  if U.QueryInterface(IStubObject, StubObject) = 0 then
    StubObject.GetStub(Stub)
  else if U.QueryInterface(IStub, Stub) <> 0 then
    CorbaDispatchError(0, CallDesc);
  R := Stub.Dispatch(CallDesc, @Params, Result^); // <- remove @
  if R <> 0 then CorbaDispatchError(R, CallDesc);
end;
 
Place #2 procedure CorbaStructDispatch(Result: PVariant; const Instance:   Variant; CallDesc: PCallDesc; Params: Pointer); cdecl;
var
  R: Integer;
  ProcResult: Variant;
begin
  if Result = nil then Result := @ProcResult;
  R := ORB.ORB.DispatchStruct(TVarData(Instance).VAny, CallDesc,
    @Params, Result^); // <- remove @
  if R <> 0 then
    CorbaDispatchError(R, CallDesc)
  else if CallDesc.CallType = DISPATCH_PROPERTYPUT then
    PVariant(@Instance)^ := Result^;
end;

Hosted by www.Geocities.ws

1