I am just starting to get more familiar with how interfaces work so bear with me if this is a trivial question.
I have two plugins (call them A and B) in the form of DLLs (not packages). There is an interface with a GUID declared in application that loads the DLL, call it IMyInterface. Both plugins see the same interface definition with the same GUID. Plugin B actually implements the interface.
Plugin A wants to find out if plugin B supports the interface IMyInterface. I use obj.GetInterface (IMyInterface, IObj) to find this out:
var IObj : IMyInterface;
obj : TObject;
obj := getPluginObjReference;
if obj.GetInterface(IMyInterface, IObj) then
showmessage ('Interface Supported');
If I call this code within plugin B, the answer is yes, which is as expected. If I use the same code (cut and paste) in plugin A, the same code claims that plugin B does not support that interface. When I trace the GetInterface call into system.pas I find that InterfaceEntry := GetInterfaceEntry(IID); return nil, hence no interface to find.
For reference, IMyInterface looks like:
IMyInterface = interface
['{277A3122-A3F2-4A14-AE56-C99230F31CE9}']
function getModel : AnsiString;
function getDescription : AnsiString;
end;
and the implementation looks like:
// Now the real class, this is private to this plugin
TModelAPI = class (TInterfacedObject, IMyInterface)
function getModel : AnsiString;
function getDescription : AnsiString;
end;
etc.
My question:
As expected plugin B rightly claims that IMyInterface is supported. Why is it that Plugin A cannot discover that plugin B supports IMyInterface? Is there a problem with interrogating interfaces across DLL boundaries?
You cannot reliably pass objects across DLL boundaries. Instead you should pass interfaces across the boundary and use as
or Supports
to query capabilities. Interfaces are designed for binary compatibility across DLL boundaries, but objects are not.
You can readily pass an IInterface
from one DLL to another and then query that. Or, if you have a common interface that all plugin objects implement, you could pass that. All that matters is that you always pass interfaces and never pass objects.
You should really use only interfaces, ie the getPluginObjReference
should return the lowest common interface supported by all the plugins and then you use Supports() function to test what interfaces (plugin versions) that particular plugin supports.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With