Обновление интерфейса обратного вызова COM

У нас проблема с интерфейсами обратного вызова точки подключения COM.

В нашем Sample.idl у нас есть несколько интерфейсов обратного вызова ISomeEvents

interface ISomeEvents : IUnknown
{
         HRESULT Event1([in]int nData);
         HRESULT Event2([in]int nData);
         HRESULT Event3([in]int nData);
}

And in the CoClass we have the following statement 
coclass MyComp
{
    [default] interface IMyInterface;
    interface IMyInterFace2;
    [default, source] interface ISomeEvents;
};

Теперь всякий раз, когда мы добавляем новые интерфейсы как часть улучшения, это не нарушает работу существующего клиента, но если расширение имеет какие-либо модификации для обратного вызова, то в конечном итоге мы обновляем интерфейс ISomeEvents, что нарушает работу существующих клиентов, мы вынуждены это сделать. потому что я думаю, что у нас может быть только один интерфейс [по умолчанию, источник].

Может ли кто-нибудь сказать мне, каков обходной путь для этого?

С уважением, Том


person user2101801    schedule 05.05.2014    source источник


Ответы (1)


Если вы разрабатываете COM-объект, в котором клиент (клиенты) работает/работает, вам действительно не следует изменять существующий интерфейс, любой интерфейс. Это всегда было фундаментальным правилом разработки COM: «интерфейсы неизменяемы»; исключения сделаны во время ранней разработки, конечно.

(Вот цитата, например: «Интерфейсы COM неизменяемы. Вы не можете определить новую версию старого интерфейса и присвоить ему тот же идентификатор». (http://msdn.microsoft.com/en-us/library/windows/desktop/ms688484%28v=vs.85%29.aspx). Найдите в Интернете «интерфейсы неизменяемы» и многое другое)

В этом случае вы должны создать новые интерфейсы ISomeEvents2, ISomeEvents3 и т. д. по мере необходимости и наследовать эти интерфейсы от предыдущей версии. Сделайте новый интерфейс своим новым источником по умолчанию.

interface ISomeEvents1 : ISomeEvents
{
    /* new enhanced events here, for use by newly compiled clients */
}

В конце концов, если вам нужно больше изменений:

interface ISomeEvents2 : ISomeEvents1
{
    /* Even newer enhanced events here, for even newer clients */
}

И так далее.

person Euro Micelli    schedule 05.05.2014
comment
у нас есть уровень взаимодействия COM и компоненты COM, и у нас есть требование, согласно которому DLL-библиотеки COM должны быть обратно совместимыми, теперь, если исходный интерфейс по умолчанию изменен, можете ли вы сказать мне, как это будет обратно совместимым, потому что более старый уровень взаимодействия будет понятия не имею о ISomeEvents2 - person user2101801; 05.05.2014
comment
Я думаю, что это должно быть хорошо. Старые клиенты, использующие старое взаимодействие, никогда не смогут использовать новые функции, что бы вы ни делали. Старое взаимодействие должно быть в состоянии продолжать реализовывать и использовать ISomeEvents без проблем. Только новые клиенты, реализующие ISomeEvents2, будут использовать дополнительные элементы. (Но я не участвовал в COM-мероприятиях уже десять лет; если вы считаете, что это неправильно, сообщите мне об этом.) - person Euro Micelli; 05.05.2014
comment
Создавая исходный интерфейс по умолчанию как ISomeEvents2, вы ломаете старые клиенты, COM должен быть совместим с версией. если у вас есть интерфейс, скажем, IMyInterface, а позже вы добавляете новый интерфейс IMyInterface2, старое клиентское приложение может продолжать использовать новую DLL и использовать IMyInterface2, это не нарушает работу клиентов, но в отношении исходных интерфейсов, я думаю, это проблема, что это решение для этого - person user2101801; 05.05.2014
comment
Я не верю, что это что-то ломает. Интерфейсы неизменяемы, а коклассы — нет. Вы всегда можете указать несколько исходных интерфейсов в IDL, а атрибут [default] просто помечает предпочитаемый вами. Код взаимодействия был построен с использованием старого предпочтения, но это просто означает, что он выбирает передачу UUID ISomeEvent (а не ISomeEvent2) в IConnectionPointContainer::FindConnectionPoint(), и ваш объект должен иметь возможность предоставить для него подходящий IConnectionPoint. Пока вы продолжаете принимать ISomeEvent в качестве допустимого интерфейса приемника, ваш клиентский код должен быть доволен. - person Euro Micelli; 05.05.2014
comment
Однако мне интересно, нужно ли вам явно указывать как ISomeEvents, так и ISomeEvents2 как [source] вместо того, чтобы полагаться только на наследование. Я не удивлюсь, если вы это сделаете. - person Euro Micelli; 05.05.2014
comment
Спасибо за разъяснение... ваша помощь очень ценится - person user2101801; 05.05.2014