在VB6中访问.NET Collection

时间:2011-06-03 19:55:52

标签: .net vb6 interop

我有一个.NET程序集,其中包含需要从VB6 dll调用的例程。 .NET程序集的例程,对于其他.NET代码,将返回对象列表。但是这对VB6不起作用。所以我使用Interop来创建一个“vb6类”,它将返回所需的数据。我读过VB.NET Collection与VB6 Collection兼容,但我发现这是不真实的。我的简单测试包括:

.NET代码:

<ClassInterface(ClassInterfaceType.AutoDual)> _
Public Class MyCOMClass

    Public Function TestMe() As Microsoft.VisualBasic.Collection
        Dim ret As New Microsoft.VisualBasic.Collection

        Dim inParam As String = "Stuff "
        ret.Add(inParam)
        ret.Add(inParam & "2")
        ret.Add(inParam & "3")
        ret.Add(inParam & "4")

        Return ret
    End Function


End Class

VB6:

Dim a As MyDotNet.MyCOMClass

Set a = New MyDotNet.MyCOMClass

Dim c As Collection

Set c = a.TestMe()

在此行,我收到“类型不匹配,错误13”错误。

我有点不知所措。我基本上需要从.NET代码中返回一个列表或项目数组 - 我已经要将现有的.NET类对象打包成一个字符串或其他东西以返回VB6(然后必须将其解压缩)所以我试图让自己稍微容易一些。

任何建议或提示都将不胜感激!

感谢。

3 个答案:

答案 0 :(得分:4)

Microsoft.VisualBasic.Collection在成员方面兼容,但它的类型不同。

为什么不直接返回数组?字符串,或COM可见的.NET类? 或者创建一个索引属性?


说完了,为什么不首先回归IListIList是COM可见的 这有效:

<Microsoft.VisualBasic.ComClass()> _
Public Class Class1

    Public Function Test() As IList
        Dim l() As String = New String() {"abc", "def", "42"}
        Return l
    End Function

End Class

Private Sub Command1_Click()
  Dim c As New ClassLibrary1.Class1

  MsgBox c.Test(2)
End Sub

答案 1 :(得分:0)

你可以使用“Microsoft.VisualBasic.Collection”返回对象的数组更轻,我从来没有正常工作,结果是你从类型转换为类型,这是怎么回事

Dim a As MyDotNet.MyCOMClass
dim ptr as variant
Set a = New MyDotNet.MyCOMClass
Dim c As Collection
ptr = a.TestMe()
Set c = ptr

如果不起作用则返回对象数组。记住你在项目设置中启用了

申请 - &gt;装配信息 - &gt;使组件COM-Visible(true) 和 编译 - &gt;注册COM互操作(true)

答案 2 :(得分:0)

如果您在使用Microsoft.VisualBasic.Collection时遇到问题,以下解决方案可能对您有用。

创建一个新对象,该对象继承.NET List类并公开COM方法以在VB6端使用。

您可以返回此新对象的单个实例,该实例可以提供对集合的访问。

此方法的最大好处是,您可以使用其他方法(例如Contains或Find)来扩展类。

示例:

Imports System.Runtime.InteropServices

<Guid("7D799AD7-9F82-44F9-A86F-DEE5A0B22268")>
<ComVisible(True)>
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>
Public Interface ITotals

    <DispId(1)>
    Function Item(i As Integer) As Total

    <DispId(2)>
    ReadOnly Property Count() As Integer

    <DispId(3)>
    Function AddTotal(label As String, weight As Double, qty As Integer) As Total   

End Interface    


<Guid("EFC518C6-781A-4A28-BF7B-A9AFC14C4F03")>
<ComVisible(True)>
<ClassInterface(ClassInterfaceType.None)>
Public Class Totals
     Inherits List(Of Total)
     Implements ITotals

     Public Shadows Function Item(i As Integer) As Total Implements ITotals.Item
         Return MyBase.Item(i)
     End Function

     Public Shadows ReadOnly Property Count() As Integer Implements ITotals.Count
         Get
             Return MyBase.Count
         End Get
     End Property

     Public Function AddTotal(label As String, weight As Double, qty As Integer) As Total Implements ITotals.AddTotal

         Dim t As New Total
         t.Label = label
         t.Weight = weight        
         t.Qty = qty      
         MyBase.Add(t)

         Return t
     End Function

End Class