如何确定对象是否支持给定的接口(两个DLL之间)

rho*_*ody 4 delphi plugins interface

我刚刚开始更熟悉界面是如何工作的,所以如果这是一个微不足道的问题请耐心等待.

我有两个插件(称为A和B)以DLL(不是包)的形式.在应用程序中声明了一个GUID的接口,它加载DLL,称之为IMyInterface.两个插件都使用相同的GUID查看相同的接口定义.插件B实际上实现了接口.

插件A想知道插件B是否支持接口IMyInterface.我使用obj.GetInterface(IMyInterface,IObj)来找出它:

var IObj : IMyInterface;
    obj : TObject;

obj := getPluginObjReference;

if obj.GetInterface(IMyInterface, IObj) then
   showmessage ('Interface Supported');
Run Code Online (Sandbox Code Playgroud)

如果我在插件B中调用此代码,答案是肯定的,这是预期的.如果我在插件A中使用相同的代码(剪切和粘贴),则相同的代码声称插件B不支持该接口.当我将GetInterface调用跟踪到system.pas时,我发现InterfaceEntry:= GetInterfaceEntry(IID); 返回nil,因此找不到接口.

作为参考,IMyInterface看起来像:

IMyInterface = interface
['{277A3122-A3F2-4A14-AE56-C99230F31CE9}']
   function getModel : AnsiString;
   function getDescription : AnsiString;
end;
Run Code Online (Sandbox Code Playgroud)

并且实现如下:

// Now the real class, this is private to this plugin
TModelAPI = class (TInterfacedObject, IMyInterface)
   function getModel : AnsiString;
   function getDescription : AnsiString;
end;
Run Code Online (Sandbox Code Playgroud)

等等

我的问题:

正如预期的那样,插件B正确声称支持IMyInterface.为什么Plugin A无法发现插件B支持IMyInterface?跨越DLL边界询问接口是否有问题?

Dav*_*nan 7

您无法跨DLL边界可靠地传递对象.相反,您应该跨越边界传递接口并使用asSupports查询功能.接口设计用于跨DLL边界的二进制兼容性,但对象不是.

您可以轻松地IInterface从一个DLL 传递到另一个DLL,然后查询它.或者,如果您有一个所有插件对象实现的通用接口,您可以传递它.重要的是你总是传递接口而不传递对象.

  • 保持"100%接口API"不仅可以帮助您的DLL与Delphi一起工作,而无需编译两者来使用运行时包,它也可以在各种Delphi版本之间工作,甚至可以在用Delphi编写的DLL和不用delphi编写的应用程序之间工作.简而言之,接口(COM)的存在是因为需要编写一个规范(一个应用程序二进制接口),它不会在编译器的发行版之间或语言之间发生变化. (2认同)

ain*_*ain 6

你应该只使用接口,即getPluginObjReference应该返回所有插件支持的最低公共接口,然后使用Supports()函数来测试特定插件支持的接口(插件版本).