У меня есть следующий 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-объект без помещения его в библиотеку типов?