开发者

Accessing .NET Collection in VB6

I have a .NET assembly that has routines that need to be called from a VB6 dll. The .NET assembly's routines, for other .NET code will return Lists of objects. However that won't work for VB6. So I am using Interop to create a "vb6 class" that will return the data needed. I had read that the VB.NET Collection is compatible with the VB6 Collection, but I've found that to be untrue. My simple test consists of:

.NET Code:

<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()

At this line, I'm receiving a "Type Mismatch, Error 13" error.

I'm kind of at a loss. I basically need to return a list or array of items from the .NET code - I'm already going to have to pack the existing .NET class object into a string or something to return to V开发者_如何学CB6 (which will then have to unpack it), so I was trying to make it slightly easier on myself.

Any suggestions or hints will be appreciated!

Thanks.


Microsoft.VisualBasic.Collection is compatible member-wise, but it's not the same type.

Why not just return an array? Of strings, or of your COM-visible .NET classes?
Or create an indexed property?


Having that said, why not return IList in the first place? IList is COM-visible.
This works:

<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


If you are encountering problems using Microsoft.VisualBasic.Collection the following solution may work for you.

Create a new object which inherits the .NET List class and exposes COM methods for use on the VB6 side.

You can the return a single instance of this new object which can provide access to the collection.

On big benefit of this method is you can extend the class with additional methods such such as Contains or Find.

Example:

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


You can return an object array, available in "Microsoft.VisualBasic.Collection". It doesn't work that well as you have to convert from type to type, e.g.:

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

If that doesn't work then return an array of objects. This needs to be enabled in Project Settings:

application -> assembly information -> Make assembly COM-Visible (true) and compile -> Register for COM interop (true)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜