COM-объект Delphi 2007 с дополнительным интерфейсом: клиент не видит интерфейс - PullRequest
0 голосов
/ 13 июня 2018

У меня есть следующий COM-объект:

unit Unit4;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
  Windows, ActiveX, Classes, ComObj, Project1_TLB, StdVcl;

const
  IID_IMyTestIntf: TGUID = '{D22502A1-B76C-4E1E-A77C-558B8A6450C1}';

type
  IMyTestIntf = interface(IUnknown)
    ['{D22502A1-B76C-4E1E-A77C-558B8A6450C1}']
  end;

  TMyTestObj = class(TTypedComObject, IMyTestObj, IMyTestIntf)
  private
  protected
  public

  end;

var
  UsedIntf: IMyTestObj;

implementation

uses ComServ;

initialization
  TTypedComObjectFactory.Create(ComServer, TMyTestObj, Class_MyTestObj,
    ciMultiInstance, tmApartment);
end.

Это библиотека типов:

const
  // TypeLibrary Major and minor versions
  Project1MajorVersion = 1;
  Project1MinorVersion = 0;

  LIBID_Project1: TGUID = '{70CAFFB4-B90D-42EF-9673-F81DB403B9BF}';

  IID_IMyTestObj: TGUID = '{26F41FF7-9C49-45D8-86BC-C38AB302B9E6}';
  CLASS_MyTestObj: TGUID = '{6F6E4B1D-100D-4DC5-A9EB-10C90BF422AB}';
type
  IMyTestObj = interface;

  MyTestObj = IMyTestObj;


  IMyTestObj = interface(IUnknown)
    ['{26F41FF7-9C49-45D8-86BC-C38AB302B9E6}']
  end;

  CoMyTestObj = class
    class function Create: IMyTestObj;
    class function CreateRemote(const MachineName: string): IMyTestObj;
  end;

implementation

uses ComObj;

class function CoMyTestObj.Create: IMyTestObj;
begin
  Result := CreateComObject(CLASS_MyTestObj) as IMyTestObj;
end;

class function CoMyTestObj.CreateRemote(const MachineName: string): IMyTestObj;
begin
  Result := CreateRemoteComObject(MachineName, CLASS_MyTestObj) as IMyTestObj;
end;

end.

Когда я пытаюсь получить IMyTestInterface the QueryInterface возвращает E_NOINTERFACE:

procedure TForm3.Button1Click(Sender: TObject);
var
  o: IMyTestObj;
  i: IMyTestIntf;
  r: HRESULT;
begin
  o := CreateComObject(CLASS_MyTestObj) as IMyTestObj;
  r := o.QueryInterface(IID_IMyTestIntf, i); //returns E_NOINTERFACE
  ShowMessage(IntToStr(r));
end;

Но если я помещу IMyTestInterface в библиотеку типов, все будет работать как положено.

Так как IMyTestInterface будет использоваться более чем в одном модуле, я не хочу добавлять его в библиотеку типов каждый раз.

Я провел некоторую отладку и обнаружил, что QueryInterface фактически выполняет два вызоваобъекты QueryInterface : один с IID_IMyTestIntf , который возвращает S_OK, а другой с GUID {AF86E2E0-B12D-4C6A-9C5A-D7AA65101E90}, который будет IInspectable , и этотвозвращает E_NOINTERFACE.

Есть ли простое решение для реализации дополнительного интерфейса в COM-объект без помещения его в библиотеку типов?

...