【问题标题】:How can you pass a custom collection class from VB.NET to VB6?如何将自定义集合类从 VB.NET 传递到 VB6?
【发布时间】:2014-06-12 05:02:16
【问题描述】:

我最近尝试将旧版 VB6 应用程序移植到 .NET。然而,它不是一个完整的端口,因为我只关注应用层。我仍然会使用一些 VB6 COM 组件。

到目前为止一切顺利,但我最近碰壁了。

我需要将自定义集合从 .NET 传递到 VB6。这可能吗?

我在 .NET 端调用的 COM 方法需要一个通用对象,但应用程序立即崩溃:InvalidCastException - 指定的转换无效。

我偶然发现了几篇文章,它们暗示了如何将 VB6 集合传递给 .NET,但反之则不然。我尝试在 .NET 中继承/利用几种不同的集合类型,但到目前为止都无济于事。任何帮助表示赞赏。

【问题讨论】:

  • @MarkJ 我看了那个问题,它似乎不是重复的。有一种方法可以让 VB6 相信它看到了 VBA.Collection,我在回答中对其进行了描述。也适用于 C#。
  • 这就是问题不同的原因——我相信@RyanMac 希望为他正在与之交谈的 VB6 组件保留二进制兼容性,可能还有二进制文件本身。 6231995 的问题和答案似乎不希望保持兼容性。
  • @Markus - 你是对的。这正是我想要做的。现在正在尝试您的实施,谢谢。
  • @MarkJ 请撤消此问题的“标记为重复”。 “从 VB6 访问 .NET 集合”与“使用 .NET 创建 VBA.Collection”不是同一个问题。

标签: .net vb.net com vb6


【解决方案1】:

在 .NET 集合类实现的 COM 接口声明中,将返回枚举数的方法的 DispId 设置为 -4。调用该方法“GetEnumerator”。

另一方面,如果你真的想模拟一个 VBA.Collection 对象,而不仅仅是在 VB6 中支持 For Each,你可以在 VB.NET 类库中设置对 VBA 类型库的引用(假设您正在创建一个类库)并在您的 VB.NET 类中实现 _Collection。

<Guid("A4C4671C-499F-101B-BB78-00AA00383CBB")>
<ComDefaultInterface(GetType(_Collection))>
<ComVisible(False)>
Public Class VBACollection
   Implements _Collection
   .
   .
   .
End Class

然后只需实现_Collection 接口。如果 VB.NET 不喜欢接口名称中的下划线,您可能需要对其进行转义。

【讨论】:

  • 仍然没有骰子。似乎 VB6 想让我为其提供 VBA.Collection 类型,但您无法在 .NET 中实例化该类(尽管您可以使用它)。
  • 啊,好的,所以 VB6 方法需要一个 VBA.Collection?或者,他们是否接受您的自定义集合类型,然后尝试使用 For Each? (因为,这需要两种不同的解决方案。)
  • 我添加了一个模拟 VBA.Collection 对象的解决方案。我原来的参考工具是 C#,我把它翻译成 VB.NET,所以如果不是 100%,我很抱歉。 (概念是一样的。)
  • @RyanMac 这可能不会影响您的测试,但我在该 GUID 的中间部分有一个额外的 9。我已经更正了这个例子。
  • 我最终在 VB6 中创建了一个桥类库,我从双方都引用了它,但您的解决方案确实有效,ProcID/DispID 提醒为我节省了无数小时试图弄清楚为什么它不会让我遍历集合。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-21
  • 2020-09-06
  • 2011-09-12
  • 1970-01-01
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
相关资源
最近更新 更多