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)
精彩评论