2011-12-11 20 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()函數測試該插件支持哪些接口(插件版本)。

相關問題