Как узнать, поддерживает ли объект данный интерфейс (между двумя DLL) - PullRequest
4 голосов
/ 11 декабря 2011

Я только начинаю знакомиться с тем, как работают интерфейсы, так что терпите меня, если это тривиальный вопрос.

У меня есть два плагина (назовите их 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');

Если я назову этот код в плагине 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;

, а реализация выглядит так:

// 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?

Ответы [ 2 ]

7 голосов
/ 11 декабря 2011

Вы не можете надежно передавать объекты через границы DLL. Вместо этого вы должны передавать интерфейсы через границу и использовать as или Supports для запроса возможностей. Интерфейсы предназначены для двоичной совместимости через границы DLL, а объекты - нет.

Вы можете легко передать IInterface из одной DLL в другую и затем запросить это. Или, если у вас есть общий интерфейс, который реализуют все объекты плагина, вы можете передать это. Все, что имеет значение, это то, что вы всегда передаете интерфейсы и никогда не пропускаете объекты.

6 голосов
/ 11 декабря 2011

Вы действительно должны использовать только интерфейсы, то есть getPluginObjReference должен возвращать наименьший общий интерфейс, поддерживаемый всеми плагинами, а затем вы используете функцию Supports () , чтобы проверить, какие интерфейсы (версии плагинов) для этого конкретного плагин поддерживает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...