[fpc-pascal]Strange compilation problems

Gabor DEAK JAHN djg at argus.vki.bke.hu
Wed Dec 27 00:50:29 CET 2000


Hello,

I had been fighting with a stubborn problem for a few days now and the 
solution came from a corner I never expected it from. The program in 
question is a small test to drive an OLE Automation server (Corel Ventura 8 
in this case), establishing the connection and calling a simple function. I 
get the strangest differences with various versions of my program. I tried 
with FPC 1.0.2, by the way.

The problem is that the enclosed program behaves differently with and 
without the unused variable marked by {*} added to the source. Without the 
variable the program does not work (it runs to the end but receives an error 
message back from the pdisp^.vtbl^.Invoke call) while with the variable it 
does work. At first I suspected some PACKRECORDS problems but the problem 
persists in all PACKRECORD configurations.

However, when specifying -al (to retain the assembler file) both versions 
work as expected. It seems to me that -al does more than simply leave the 
assembler file there, the resulting EXEs are drastically different.

When this will be sorted out, I'll have new problems: if this program is 
divided into a unit and a main program, it does not work even with -al, but 
let's proceed one step at a time... :-)))

Note that the original Ole2.pp in FPC is not functioning, make sure to use 
the one enclosed here (although I don't know how anybody could test it 
without Ventura installed, however, it might be modified to call another OLE 
server; as far as I know, MS Office programs are possible candidates).

-------------------- TEST.PP
{$APPTYPE CONSOLE}
program VPDoctor;
{$PACKRECORDS NORMAL}
uses
  Windows, Ole2;
const
  CLSCTX_INPROC_SERVER = 1;
  CLSCTX_LOCAL_SERVER = 4;
  CLSCTX_REMOTE_SERVER = 16;
  CLSCTX_SERVER = CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER or
CLSCTX_REMOTE_SERVER;
  DISPATCH_METHOD = 1;
  IID_IUnknown : GUID = (Data1 : 0; Data2 : 0; Data3 : 0; Data4 : ($C0, 0, 0,
0, 0, 0, 0, $46));
  IID_IDispatch : GUID = (Data1 : $00020400; Data2 : 0; Data3 : 0; Data4 :
($C0, 0, 0, 0, 0, 0, 0, $46));
  IID_NULL : GUID = (Data1 : 0; Data2 : 0; Data3 : 0; Data4 : (0, 0, 0, 0, 0,
0, 0, 0));
  ProgID : PChar =
'C'#0'o'#0'r'#0'e'#0'l'#0'V'#0'e'#0'n'#0't'#0'u'#0'r'#0'a'#0'.'#0'A'#0'u'#0'
t'#0'o'#0'm'#0'a'#0't'#0'i'#0'o'#0'n'#0'.'#0'8'#0#0;
type
  PDispID = ^TDispID;
  TDispID = cardinal;
  PExcepInfo = pointer;
  PIUnknown = ^IUnknown;
  PDispParams = ^TDispParams;
  TDispParams = packed record
    rgvarg : PVariant;
    rgDispIDNamedArgs : PDispID;
    cArgs : word;
    cNamedArgs : word;
    end;
  PIDispatch = ^IDispatch;
  IDispatch = packed record
    vtbl : ^IDispatchVtbl;
    end;
  IDispatchVtbl = packed record
    QueryInterface : function (const pdisp : PIDispatch; const iid: TIID; var
obj): hResult; stdcall;
    AddRef : function (const pdisp : PIDispatch) : longint; stdcall;
    Release : function (const pdisp : PIDispatch) : longint; stdcall;
    GetTypeInfoCount : function (const pdisp : PIDispatch; pctinfo : PUINT) :
hResult; stdcall;
    GetTypeInfo : function (const pdisp : PIDispatch; iTInfo : word; lciid :
LCID; var ppTInfo) : hResult; stdcall;
    GetIDsOfNames : function (const pdisp : PIDispatch; const iid : TIID;
rgszNames : LPCWSTR; cNames : UINT; lciid : LCID; var DispID : TDispID) :
hResult; stdcall;
    Invoke : function (const pdisp : PIDispatch; dispIdMember : TDispID; const
iid : TIID; lciid : LCID; wFlags : WORD; pDP : PDispParams; pVarResult :
PVariant; pExceptInfo : PExcepInfo; puArgErr : PUINT) : hResult; stdcall;
    end;
var
  hr : hResult;
  CLSID_Ventura : TCLSID;
  punk : ^IUnknown;
  pdisp : ^IDispatch;
  dp : TDispParams;
  dispid : TDispID; {*}

function CLSIDFromProgID (lpszProgID : LPCWSTR; var pclsid : TCLSID) :
hResult;
external 'OLE32' name 'CLSIDFromProgID';
function CoCreateInstance (rclsid : TCLSID; pUnkOuter : PIUnknown;
dwClsContext
: longint; riid : TIID; var ppv) : hResult; external 'OLE32' name
'CoCreateInstance';
function OleInitialize (pvReserved : pointer) : hResult; external 'OLE32' name
'OleInitialize';
procedure OleUninitialize; external 'OLE32' name 'OleUninitialize';

begin
  dp.rgvarg := nil;
  dp.rgDispIDNamedArgs := nil;
  dp.cArgs := 0;
  dp.cNamedArgs := 0;
  hr := OleInitialize (nil);
  hr := CLSIDFromProgID (LPCWSTR(ProgID), CLSID_Ventura);
  hr := CoCreateInstance (CLSID_Ventura, nil, CLSCTX_SERVER, IID_IUnknown,
punk);
  hr := punk^.vtbl^.QueryInterface (punk, IID_IDispatch, pdisp);
  hr := pdisp^.vtbl^.Invoke (pdisp, $0883, IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD, @dp, nil, nil, nil);
  OleUnInitialize;
end.


--------------- OLE2.PP
unit ole2;
{$PACKRECORDS 1}
  interface

    uses
       windows;

    type
      PIUnknown = ^IUnknown;
      IUnknown = packed record
        vtbl : ^IUnknownVtbl;
        end;
      IUnknownVtbl = packed record
        QueryInterface : function (const punk : PIUnknown; const iid: TIID;
var
obj): HResult; stdcall;
        AddRef : function (const punk : PIUnknown) : longint; stdcall;
        Release : function (const punk : PIUnknown) : longint; stdcall;
        end;

  implementation

end.


Regards,

   Gabor DEAK JAHN

-------------------------------------------------------------------
Gabor DEAK JAHN -- Budapest, Hungary.
WWW: <http://www.tramontana.co.hu/>www.tramontana.co.hu
E-mail: djg at tramontana.co.hu





More information about the fpc-pascal mailing list