VB6 二进制兼容性 - 添加新事件
在 VB6 ActiveX exe 项目中,如果添加新事件,是否有任何方法可以保留事件调度接口的 GUID?
显然,更改现有事件会破坏兼容性。添加新的不会导致 VB6 IDE 发出警告。不过,这并不让我感到惊讶,因为当您添加新方法时它也不会发出警告,但至少现有方法保留了它们的 GUID。
对于事件,如果以后添加新事件,似乎无法保留现有事件的向后兼容性。
对于通过 COM 集成的 VB6 应用程序来说,这似乎不是问题;我认为 VB 运行时会巧妙地通过注册表来获取事件,而无需预先知道 GUID。
如果另一个应用程序是 .Net(特别是 C#),并且我必须手动声明接口才能实现事件接收器,我希望 GUID 保持不变,以避免每当 VB6 时都需要重新编码 i/f应用程序已扩展。我可能既不知道也不关心 VB6 应用程序中新实现的事件 - 我只是希望能够继续使用预先存在的事件而不需要更改 .Net 源代码。
是否有一些我错过的 VB6 技巧可以让我做到这一点?
In a VB6 ActiveX exe project, is there any way to preserve the GUID for the events dispinterface if and when new events are added?
Obviously changing existing events breaks compatibility. Adding a new one doesn't cause the VB6 IDE to issue a warning. This doesn't really surprise me, though, as it also doesn't warn when you add new methods but at least the existing methods retain their GUIDs.
With events, there seems to be no way to retain backwards compatibility for existing ones if new ones are added later.
This doesn't seem to be an issue for VB6 applications integrating via COM; I assume the VB runtime does something clever to pick up on the events via the registry without needing to know the GUID up-front.
Where the other app is .Net (specifically C#) and I have to declare the interface by hand in order to implement the event sinks, I want the GUID to remain constant to avoid the need for re-coding the i/f whenever the VB6 app is extended. I may neither know nor care about the newly-implemented events in the VB6 app - I just want to be able to continue to use the pre-existing ones without needing to change the .Net source code.
Is there some VB6 trick that I'm missing out on that would enable me to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题在于,COM 接口一旦定义就保持不变。然而,COM 具有版本控制功能,因此可以将旧接口设置为与新接口兼容。
Visual BASIC 在幕后所做的就是创建一个新版本的 com 界面。更新版本号,添加新方法并设置所需信息,以便新界面可以自动与旧界面一起使用。
正如它指出的那样,事件似乎不是自动完成的。我使用 Visual Studio OLE/COM 对象视图并看到 GUID 更改。
混合 VB6/.NET 的一个可能的解决方案有点麻烦,但在您进行更改时可以让一切保持清晰。首先,您需要使用 OLE/COM 对象视图来获取 VB6 对象的 IDL。然后使用 MIDL 编译器生成类型库。从现在开始,使用 typelib 作为您的参考。
您必须重命名该接口,因为它将与 VB6 名称冲突。这个想法是.NET 和 VB6 都将引用类型库并实现接口。每当您想要更新接口时,您都可以更改 IDL、重新编译类型库并实现两者的接口。
现在,如果这听起来有点复杂,那就继续 WFT 吧!?我不怪你。但在我自己的转换项目中,我发现它在某些情况下很有用,当 VB6 内容仍在不断开发但您需要在 .NET 中使用它时,
现在一个简化的解决方案可能是识别和分离两个组件互操作所需的最低限度。说出事件和一些属性。生成该接口的 IDL。编译一个类型库并将其用作参考。我也这样做过。
The problem is that once defined a COM interface is invariant. However COM has versioning so that a older interface can be setup as compatible with a new interface.
What Visual BASIC does behind the scene is creates a NEW version of the com interface. Update the version number, adds the new methods and setup the needed info so that the new interface can be automatically used with the older interface.
As it pointed out it looks like that Events are not done automatically. I used Visual Studio OLE/COM Object View and see the GUID change.
A possible solution for a hybrid VB6/.NET is a bit of pain but keeps everything clear as to when you make changes. First you need need to use the OLE/COM Object view to get the IDL of the VB6 object. Then use the MIDL compiler to generate a typelib. From now on use the typelib as your reference.
You will have to rename the interface as it will conflict with VB6 Name. The idea is that both the .NET and the VB6 will reference the typelib and implement the interfaces. Anytime you want to update the interface you change the IDL, recompile the typelib and implement the interface for both.
Now if this sound a bit complex and leave going WFT!? I don't blame you. But in my own conversion project I found it useful in certain circumstances when the VB6 stuff still has ongoing development but you need to use it in .NET
Now a simplifier solution could be to identify and separate the minimum needed for two components to interoperate. Say the events and some properites. Generate the IDL for that interface. Compile a typelib and use that as the reference. I have done that as well.
我从未找到一种方法来防止添加事件时破坏兼容性。不幸的是,这是我必须第一次就做对的事情之一(获取所有新事件、参数等),这样当我破坏兼容性时,我只需要经历一次这种痛苦。
I've never found a way to prevent broken compatibility when adding events. Unfortunately, this is one of those things that I have to get right the first time (get all my new events, parameters, etc.) so that when I break compatibility, I only have to go through that pain once.
恐怕我也没有找到在更改事件时保持 GUID 常量的任何方法..但是如果您仅在 .NET 应用程序中使用 VB6 程序集,您可以在每次重新创建它时只 tlbimp VB6 dll ,然后创建对此的引用,而不是在 .NET 中手动编写接口?
I'm afraid I haven't found any way of keeping the GUID constants when changing events either.. but if you're only using the VB6 assembly in a .NET app, can you just tlbimp the VB6 dll each time you recreate it, then create a reference to that instead of writing the interface in .NET by hand?