【问题标题】:Marshal a .NET ArrayList to VB6 [Com interop]将 .NET ArrayList 编组到 VB6 [Com 互操作]
【发布时间】:2014-12-17 05:14:59
【问题描述】:

我有一个相对简单的 C#class,我想将它编组到一个 VB 项目中。它看起来像这样(我为这篇文章简化了一点):

[Guid("AAAAAAAA-AAAA-AAAA-AAAA-123456789ABC", ClassInterface(ClassInterfaceType.AutoDual), ComVisible(true)]
[ProgId("MyBiz.MyResponse")
[Serializable]

public class MyResponse
{
    public bool Success { get; set; }
    public int ID{ get; set; }
    public string Location{ get; set; }

    public ArrayList Messages { get; set; }
}

消息包含 0 个或多个字符串。我编译它并创建一个供 VB6 使用的类型库。就从简单类型传递的数据而言,一切都很好,但是 Messages 变量,虽然 VB 运行时将其识别为 ArrayList,但即使它应该包含任何数据,它也不包含任何数据。在整理数据方面,我错过了什么?我知道泛型不会编组,但我相信 ArrayList 可以。我是否缺少某个属性或其他内容?

不需要提供替代解决方案,因为我问这个是因为我想知道如何做到这一点,而不是因为如果我可以让它发挥作用我没有替代方案。谢谢!

【问题讨论】:

  • 我不敢相信 VB 6 会识别一个数组列表,因为它没有这样的功能,除非你从你的 VB6 程序中引用 .net 框架(这是可能的,但你没有提到那)。我知道您说过您对替代方案不感兴趣,但是如果您想要 VB6 可以在没有 .Net 的情况下“看到”的东西,请尝试其他一些共同点(例如,脚本库 Dictionary 对象或数组)
  • 我也没有看到它。这是一个正在流传的帖子:hightechtalks.com/dotnet-framework-interop/…
  • 我认为我之前成功地做到了这一点......像 ArrayList 这样的东西在你的类型库中用 IDL 编写,所以 VB6 知道它的属性,然后对 Item 的调用以获取数据被编组为一个对象或一个变体。如果数据不能正确编组,请在 .NET 中编写一个 IArrayList 接口,以便您可以使用属性自己指定编组。
  • 我的印象是,虽然泛型无法编组,但 ArrayList 可以 - 不过,我可能错了。 @FastAi - 我没有引用 VB6 中的 .NET 框架。我认为有趣的是,它在 VB6 的监视窗口中使用数组列表的变量名称识别 ArrayList,它只是没有值。
  • 没有什么可以想象的原因这不起作用,您不会神奇地从该 ArrayList 中获得一个空的 IList 或 IEnumerable。如果您在 VB6 程序使用时不知道如何调试您的 C# 代码,那么请提出一个明确的问题。类设计上有很多问号,客户端代码分配一个新的 ArrayList 是非常很少有用的。删除 setter,使属性类型 IList 或 IEnumerable。现在您可以在代码中使用List<string>

标签: c# com vb6 interop marshalling


【解决方案1】:

处理此问题的一种方法是使用 COM SafeArray 将数据从 .NET 来回传递到 COM。我使用这种技术比使用 ArrayList 更幸运。您的消息声明可能如下所示:

[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
public string[] Messages

这在 VB6 或类似的 COM 客户端中可以看到

Public Messages() as String

一个 COM SafeArray 字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 2010-12-24
    • 1970-01-01
    • 2010-11-20
    相关资源
    最近更新 更多