Search code examples
delphicom

How to program a COM object with an IEnumerator, IEnumerable interface inside


I am trying to program a COM object with the Enumerable and Enumerator inside in Delphi. It's a nightmare. First in the .ridl file: enter image description here next in the _tlb.pas I have this:

// *********************************************************************//
// Interface :   ITrackingRatesCol
// Indicateurs : (4416) Dual OleAutomation Dispatchable
// GUID :        {F116E1DA-7E3E-4207-BD17-1615DCE4BE41}
// *********************************************************************//
  ITrackingRatesCol = interface(IEnumerable)
    ['{F116E1DA-7E3E-4207-BD17-1615DCE4BE41}']
    function Get_Count: Integer; safecall;
    property Count: Integer read Get_Count;
  end;

// *********************************************************************//
// DispIntf :    ITrackingRatesColDisp
// Indicateurs : (4416) Dual OleAutomation Dispatchable
// GUID :        {F116E1DA-7E3E-4207-BD17-1615DCE4BE41}
// *********************************************************************//
  ITrackingRatesColDisp = dispinterface
    ['{F116E1DA-7E3E-4207-BD17-1615DCE4BE41}']
    property Count: Integer readonly dispid 1;
    function GetEnumerator: IEnumVARIANT; dispid -4;
  end;

And in my .pas file of my object:

  TTrackingRatesCol = class(TAutoObject, ITrackingRatesCol,IEnumerable)
   private
      fIndex,fCount:integer;
  protected
    function GetCurrent:driverates;safecall;
    function Get_Count: Integer; safecall;
    function MoveNext: WordBool; safecall;
    function GetEnumerator: IEnumerator; safecall;
   public
      procedure Initialize; override;
      destructor Destroy; override;
  end;

implementation

uses ComServ,Data.Win.ADODB,Core,SysUtils;

function TTrackingRatesCol.GetEnumerator: IEnumerator;
begin
  result:=self;
end;

But I have allways the message: that the implementation of the interface IEnumerable.GetEnumerator is missing!! Thanks a lot for your help.

Michel


Solution

  • tl;dr: Remove the safecall

    The definition of IEnumerable:

      IEnumerable = interface(IInterface)
        function GetEnumerator: IEnumerator;
      end;
    

    Yours:

    function GetEnumerator: IEnumerator; safecall;
    

    Or, side-by-side:

    function GetEnumerator: IEnumerator;             // definition
    function GetEnumerator: IEnumerator; safecall;   // yours