Как да кажа на vb6 да не създава нови версии на интерфейси/com обекти всеки път, когато правя dll?

Имам vb6 com сървър (ActiveX DLL проект), който се използва от .NET код

Всеки път, когато правя промени в кода на vb6 и правя dll, трябва да прекомпилирам и своя .NET клиентски код, защото изглежда, че VB6 генерира нови GUID или версии на интерфейси и com-обекти.

Признавам, че това е добра практика, защото се правят промени, но бих искал да деактивирам това поведение, за да оставя моя .NET клиентски код да бъде един и същ всеки път, когато актуализирам своята vb6 dll.

Как мога да кажа на VB6 да запази всички GUID и версии за ActiveX dll едни и същи, без значение какви промени се правят на COM обекти или COM интерфейси?


person user149691    schedule 09.06.2014    source източник
comment
Вижте Изграждане, създаване на версии и поддръжка на компоненти на Visual Basic и обсъждането на опциите за проектна и двоична съвместимост.   -  person Damien_The_Unbeliever    schedule 09.06.2014


Отговори (3)


Изборът в раздела Project + Properties, Components има значение. Трябва да изберете „Двоична съвместимост“ тук, за да го принудите да използва повторно стари ръководства. И дръжте копие на DLL наоколо, за да действа като "главен", който предоставя ръководствата, проверете го в контрола на източника.

Когато добавяте нови класове, вие също трябва да актуализирате това копие, така че бъдещите версии да знаят да използват повторно същите ръководства за тези добавени класове. Лесно за забравяне, доста трудно за диагностициране, когато го направите.

Много е опасно, повторното използване на ръководства е много силен индуктор на ада на DLL. Можете да накарате старите клиентски програми да продължат да използват новата DLL, стига да избягвате промяната на съществуващите методи. Не само техният подпис на метода, но и тяхното изпълнение. Актуализиран клиент, който среща стара версия на DLL, ще се провали по много неприятен начин, сривът при нарушение на достъпа е почти невъзможно да се диагностицира.

person Hans Passant    schedule 09.06.2014

Използването на двоична съвместимост ви печели само толкова много. Поддържането на съвместимост на интерфейса в дългосрочен план работи добре само за много прости библиотеки или когато вашите интерфейси са много добре планирани и подготвени за бъдещето от самото начало. Може да бъде страшно да погледнете VB6 библиотеките на някои хора и да видите номерата на версията на интерфейса в стотици (както GUID, така и номерата на версията се използват за идентифициране на интерфейс), дори когато смятат, че внимателно са управлявали двоичната съвместимост.

Може да стане още по-лошо, когато имате система от програми, които споделят библиотеки. Ново изискване или дори корекция на грешка може да изисква критична промяна в интерфейса на библиотеката за една програма, но не и за останалите 12 или 20 от тях.

Трябва да се приспособите към това чрез изрично ръчно създаване на версии, при което всъщност променяте името на библиотеката, за да отразява нова версия с изцяло нов набор от GUID. Често това се прави с номериране, така че ProgId като "FuddInvLib1.DalRoot" може да съществува паралелно с нов "FuddInvLib2.DalRoot" в две библиотеки с напълно различни набори от GUID: FuddInvLib1.dll и FuddInvLib2.dll.

Тъй като всеки се променя за целите на поддръжката, можете да поддържате двоично съвместими версии в всеки от тях с течение на времето, като в крайна сметка напълно премахнете FuddInvLib1.dll. Това разбира се означава мигриране на клиентския код, за да използвате по-новата библиотека или библиотеки с течение на времето, но имате лукса да правите това постепенно с планирано темпо.

person Bob77    schedule 09.06.2014

Договорът за COM предвижда, че дефинициите на интерфейса са неизменни (без промяна на имената на методите, списъците с аргументи, реда на методите, броя на методите), но че реализациите могат да бъдат свободно променяни. Наивно, но вярно. (VB Binary съвместимостта няма да ви позволи да променяте сигнатурите на методите или реда на методите в интерфейс, въпреки че ще ви позволи да добавяте нови методи към него – вижте). Независимо от това, правенето на каквато и да е промяна в интерфейс или неговите методи за DLL, който е в производство, е „най-лошата практика“, както доказаха годините на DLL Hell и както Ханс обясни.

Един подход за запазване на двоичната съвместимост чрез промени във версията е да се добавят нови интерфейси към компонента и никога (никога) да не се докосват старите интерфейси, след като някоя версия на DLL е в производство. Старият клиент с удоволствие ще използва стария интерфейс, а по-новите клиенти могат да използват новия интерфейс.

Новият клиент, използващ стара интерфейсна грешка, може да бъде прихванат с помощта на метода iUnknown.QueryInterface. Във VB можете да направите това:

If Not TypeOf myObjectReference Is myNewInterface Then
    'gracefully handle the error
End If

Това ще извика метода QueryInterface и ще върне false, ако препращате към по-стара версия на DLL. Можете да изпратите съобщение до потребителя, че трябва да инсталира по-новата версия на DLL и да излезете. Можете да обвиете тази функционалност във функция и да я извикате, когато инициализирате обекта във вашия нов клиент. Ако новият интерфейс не се поддържа, имате стара версия на DLL; можете да изпратите съобщение до потребителя да инсталира по-новата версия и да преминете оттам.

person BobRodes    schedule 12.06.2014