Csharp/C#教程:如何告诉vb6每次创建dll时都不要创建新版本的interfaces / com对象?分享


如何告诉vb6每次创建dll时都不要创建新版本的interfaces / com对象?

我有.NET代码使用的vb6 com服务器(ActiveX DLL项目)

每次我将更改放入vb6代码并生成dll时,我也必须重新编译我的.NET客户端代码,因为它看起来像VB6为接口和com对象生成新的GUID或版本。

我承认这是一个很好的做法,因为进行了更改,但我想禁用此行为,以便每次更新我的vb6 dll时都让我的.NET客户端代码相同。

无论对COM对象或COM接口做了哪些更改,我怎么能告诉VB6保持ActiveX dll的所有GUID和版本都一样?

Project + Properties,Components选项卡中的选择很重要。 您必须在此处选择“二进制兼容性”以强制它重新使用旧的guid。 并保留DLL的副本作为提供guid的“主”,将其检入源代码控制。

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

这是非常危险的,重用guids是一个非常强大的DLL Hell诱导器。 只要您小心避免更改现有方法,就可以使旧的客户端程序继续使用新的DLL。 不仅是他们的方法签名,还有他们的实现。 遇到旧版DLL的更新客户端将以非常恶劣的方式失败,访问冲突崩溃几乎无法诊断。

使用二进制兼容性只会为您买得太多。 长期维护接口兼容性仅适用于非常简单的库,或者当您的接口从一开始就经过精心规划和面向未来时。 看一些人的VB6库并看到高达数百的接口版本号(GUID和版本号都用于识别接口)可能很可怕,即使他们认为他们已经仔细管理二进制兼容性。

当你拥有一个共享库的程序系统时,它会变得更糟。 新要求甚至错误修复可能需要对一个程序的库接口进行重大更改,而不是其他12个或20个程序。

您必须通过显式手动版本控制来适应这一点,您实际上更改了库的名称以反映具有全新GUID集的新版本。 通常这是通过编号来完成的,因此像“FuddInvLib1.DalRoot”这样的ProgId可以与具有完全不同的GUID集的两个库中的新“FuddInvLib2.DalRoot”并存:FuddInvLib1.dll和FuddInvLib2.dll。

由于每个都是为了支持目的而更改,您可以随着时间的推移每个版本中保持二进制兼容版本,最终完全淘汰FuddInvLib1.dll。 这当然意味着迁移客户端代码以便随着时间的推移使用更新的库或库,但您可以按计划的速度逐步增加。

COM合同规定接口定义是不可变的(不改变方法名称,参数列表,方法顺序,方法数量),但可以自由地改变实现。 天真,但是真的。 (VB二进制兼容性不允许您更改接口中的方法签名或方法顺序,尽管它允许您向其添加新方法 – 参见图)。 尽管如此,对于生产中的DLL的接口或其方法进行任何更改都是“最糟糕的做法”,因为多年的DLL Hell已经证实并且正如Hans所解释的那样。

通过版本更改保留二进制兼容性的一种方法是向组件添加新接口,并且在生产任何版本的DLL后永远(永远不会)触摸旧接口。 旧客户端将很乐意使用旧接口,而较新的客户端可以使用新接口。

使用旧接口错误的新客户端可以使用iUnknown.QueryInterface方法进行捕获。 在VB中,您可以这样做:

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

这将调用QueryInterface方法,如果引用旧版本的DLL,则返回false。 您可以通知用户他需要安装较新版本的DLL并退出。 您可以将此function包装到一个函数中,并在初始化新客户端中的对象时调用它。 如果不支持新接口,则您拥有旧版本的DLL; 您可以通知用户安装较新版本并从那里开始。

上述就是C#学习教程:如何告诉vb6每次创建dll时都不要创建新版本的interfaces / com对象?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/1281672.html

(0)
上一篇 2022年11月28日
下一篇 2022年11月28日

精彩推荐