我如何告诉vb6不创建新版本的接口/com对象,每次我做dll

本文关键字:对象 com dll 接口 何告诉 vb6 新版本 创建 | 更新日期: 2023-09-27 18:07:50

我有。net代码使用的vb6com服务器(ActiveX DLL项目)

每次我对vb6代码进行更改并制作dll时,我都必须重新编译我的。net客户端代码,因为它看起来像vb6生成新的guid或接口和com对象的版本。

我承认这是一个很好的做法,因为改变了,但我想禁用这种行为,让我的。net客户端代码是相同的,每次我更新我的vb6 dll。

我怎么能告诉VB6保持ActiveX dll的所有guid和版本相同,无论对COM对象或COM接口做了什么改变?

我如何告诉vb6不创建新版本的接口/com对象,每次我做dll

Project + Properties, Components选项卡中的选择很重要。您必须在这里选择"二进制兼容性"来强制它重新使用旧的指南。并保留一个DLL的副本,作为提供指南的"主",将其检入源代码控制。

当你添加新类时,你也必须更新该副本,以便将来的版本将知道为这些添加的类重用相同的指南。很容易忘记,当你忘记的时候却很难诊断。

这是非常危险的,重用指针是一个非常强大的DLL地狱诱导器。您可以让旧的客户端程序继续使用新的DLL,只要您小心避免更改现有的方法。不仅是它们的方法签名,还有它们的实现。更新后的客户端遇到旧版本的DLL将以非常令人讨厌的方式失败,访问冲突崩溃几乎无法诊断。

使用二进制兼容性只会给你带来这么多。长期维护接口兼容性只适用于非常简单的库,或者当您的接口从一开始就规划得非常好并经得起未来的检验时。查看某些人的VB6库并看到接口版本号高达数百(guid和版本号都用于识别接口)可能会让人感到害怕,即使他们认为自己已经仔细管理了二进制兼容性。

当你有一个共享库的程序系统时,情况会变得更糟。一个新的需求,甚至一个bug修复可能需要对一个程序的库接口进行破坏性的更改,而不是对其他12个或20个程序的库接口进行破坏性的更改。

您必须通过显式的手动版本控制来适应这一点,在这种情况下,您实际上更改了库的名称,以反映具有全新guid集的新版本。这通常是通过编号来完成的,所以像"FuddInvLib1"这样的ProgId。"DalRoot"可以与新的"fuddinvlib"共存。在两个库中使用完全不同的guid集:FuddInvLib1.dll和FuddInvLib2.dll。

由于每个都是出于支持目的而更改的,您可以在中维护二进制兼容版本,最终完全淘汰FuddInvLib1.dll。这当然意味着随着时间的推移将客户端代码迁移到使用更新的库,但是您可以按照计划的速度增量地执行此操作。

COM契约规定接口定义是不可变的(不能改变方法名、参数列表、方法顺序、方法数量),但实现可以自由更改。天真,但却是事实。(VB二进制兼容性将不允许您更改接口中的方法签名或方法顺序,尽管它允许您向其添加新方法——请参见图)。然而,对生产中的DLL的接口或方法进行任何更改都是"最糟糕的做法",正如多年的DLL地狱所证明的那样,正如Hans所解释的那样。

通过版本变更保持二进制兼容性的一种方法是向组件添加新接口,并且一旦任何版本的DLL投入生产,就永远不要(永远不要)触及旧接口。旧客户端将愉快地使用旧接口,而新客户端可以使用新接口。

使用旧接口错误的新客户端可以通过使用iUnknown来捕获。QueryInterface方法。在VB中,你可以这样做:

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

这将调用QueryInterface方法,如果引用的是旧版本的DLL,则返回false。您可以通知用户他需要安装较新版本的DLL并退出。您可以将此功能包装成一个函数,并在新客户机中初始化对象时调用它。如果不支持新接口,说明您使用的是旧版本的DLL;你可以通知用户安装新版本,然后从那里开始。