[fpc-pascal] IDispatch with Variant is not working on Linux. Why?

Anthony Walter sysrpl at gmail.com
Wed Nov 1 02:07:27 CET 2023


Is there any reason why the late binding of properties and methods through
of IDispatch interface with the Variant type is not working on Linux?

I am writing a cross platform embeddable JavaScript toolkit for Free
Pascal. I wanted to use IDispatch with variants so that the experience with
be more fluid for eventual end users. My goal of was to allow code like
this to run:

var
  Script: IScript;
  V: Variant;
begin
  Script := NewScript('let person = {"name":  "James", age: 24}; let speak
= () => log(person.name)')
  V := Script.This;
  V.person.name = 'Ralph';
  V.speak(); // writes out Ralph
  V := V.person;
  WriteLn(V.age); // write out 24
  V.address.street := '123 Skippy Lane'; // add address object with a
street to person
  WriteLn(V.state); // writes out Undefined
end;

In the above code Script.This is a property returning an IDispatch
interface holding an internal reference to the top level script object. The
problem I am having with my current trunk version of fpc is that when I use
a Variant that is assigned an IDispatch, no IDispatch methods to lookup and
things like "person", "name", or "age" are ever evaluated.

Instead I get this:

Project dispatcher raised exception class 'External: SIGSEGV'.

Here is an example program. Not one WriteLn() in the example ever executes.
Instead at runtime when V.Hello is evaluated I get the above exception. I
believe fpc does support late time binding of IDispatch even on Linux as no
inherent tie to Microsoft Windows functions are needed to make use of the
IDispatch interface. So what is going on?

program Dispatcher;

{$mode delphi}

type
  TDispatcher = class(TInterfacedObject, IDispatch)
  public
    function GetTypeInfoCount(out Count: LongInt): HResult; stdcall;
    function GetTypeInfo(Index, LocaleID: LongInt; out TypeInfo): HResult;
stdcall;
    function GetIDsOfNames(const IID: TGUID; Names: Pointer;
      NameCount, LocaleID: LongInt; DispIDs: Pointer): HResult; stdcall;
    function Invoke(DispID: LongInt;const IID: TGUID; LocaleID: LongInt;
      Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer):
HResult; stdcall;
  end;

function TDispatcher.GetTypeInfoCount(out Count: LongInt): HResult;
begin
  WriteLn('GetTypeInfoCount');
  Count := 0;
  Result := S_OK;
end;

function TDispatcher.GetTypeInfo(Index, LocaleID: LongInt; out TypeInfo):
HResult;
begin
  WriteLn('GetTypeInfo');
  Result := E_NOTIMPL;
end;

function TDispatcher.GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount,
  LocaleID: LongInt; DispIDs: Pointer): HResult;
begin
  WriteLn('GetIDsOfNames');
  Result := S_OK;
end;

function TDispatcher.Invoke(DispID: LongInt; const IID: TGUID;
  LocaleID: LongInt; Flags: Word; var Params; VarResult, ExcepInfo,
  ArgErr: Pointer): HResult;
begin
  WriteLn('Invoke');
  Result := S_OK;
end;

procedure Test;
var
  D: IDispatch;
  V: Variant;
begin
  D := TDispatcher.Create;
  V := D;
  V.Hello();
end;

begin
  Test;
end.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20231031/dd49e886/attachment.htm>


More information about the fpc-pascal mailing list