2011-12-11 32 views
4

如果这是一个微不足道的问题,我开始更加熟悉接口如何工作。如何找出对象是否支持给定的接口(两个DLL之间)

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

插件A想知道插件B是否支持接口IMyInterface。我用obj.GetInterface(IMyInterface的,IObj)发现了这一点:

如果我插件B内部调用此代码,答案是肯定的,这是符合市场预期。如果我在插件A中使用相同的代码(剪切和粘贴),则相同的代码声明插件B不支持该接口。当我将GetInterface调用追踪到system.pas中时,我发现InterfaceEntry:= GetInterfaceEntry(IID);返回零,因此没有界面来查找。

仅供参考,IMyInterface的样子:

IMyInterface = interface 
['{277A3122-A3F2-4A14-AE56-C99230F31CE9}'] 
    function getModel : AnsiString; 
    function getDescription : AnsiString; 
end; 

和实现的样子:

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

我的问题:

正如预期的那样插件的使用b正确主张IMyInterface受支持。为什么插件A无法发现插件B支持IMyInterface?跨DLL边界查询接口是否存在问题?

+1

我很高兴地报告,ain和Heffernan给出的答案提供了解决问题的必要信息。我停止了传递对象,而是在插件之间传递IInterface,然后我使用supports方法来找出实际支持哪些接口并且工作。我现在可以将插件分类为他们据说可以做的事情。非常感谢您的帮助。正确的答案是赫弗南,因为他给出了更全面的答案,但基本上都是正确的。 – rhody

回答

7

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

您可以随时将IInterface从一个DLL传递到另一个,然后查询该DLL。或者,如果你有一个所有插件对象实现的通用接口,你可以通过它。重要的是你总是传递接口并且永远不传递对象。

+2

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

6

您应该只使用接口,即getPluginObjReference应返回所有插件支持的最低通用接口,然后使用Supports()函数测试该插件支持哪些接口(插件版本)。

相关问题