从互操作调用返回多个结果(UDT?) - VB6< - > VB.NET

时间:2012-05-07 21:25:24

标签: vb.net vb6 com-interop

我希望Interop用户控件(VB.NET)返回并接受来自get / set调用的多个值。我假设用户定义的类型(UDT),将是正确的方式,但我不断从VB6编译获得“变量使用Visual Basic中不支持的自动化类型”。如何在互操作控件和VB6应用程序之间传递多个值?

VB.NET(Interop)代码,一个带有.NET ListView的控件

Structure Employee
    Dim Firstname As String
    Dim Lastname As String
End Structure

...

Public Property MyReadListViewData() As Employee
    Get
        Dim myEmployee As Employee
        myEmployee.Lastname = ListView1.SelectedItems(0).Text
        Return myEmployee
    End Get
    Set(ByVal value As Employee)
        Me.ListView1.SelectedItems(0).Text = value.Lastname
    End Set
End Property

典型的VB6代码:

Private Sub Command4_Click()
    Dim myEmployee As Employee
    myEmployee = MyToolStrip1.MyReadListViewData
    Text3.Text = myEmployee.Lastname
End Sub

2 个答案:

答案 0 :(得分:0)

您是否考虑过将“内容”作为数据集或使用XML序列化?我对VB6并不熟悉,但我认为这样可行。为了在两个任何东西之间传递一个自定义的东西,他们都必须“意识到”那个东西。

您还可以在互操作周围创建一个包装器,以便您可以添加对您的东西的引用,以避免代码重复。我不能肯定地说,但我不知道如何让让你的东西在两者之间通过

答案 1 :(得分:0)

您获取“变量”的原因是使用Visual Basic中不支持的自动化类型' VB6中的错误是因为类型库中创建的记录不符合VB6。我创建了一个新的VB2005项目,COM Visible设置为true:

Public Class Boing

    Public Structure Employee
        Dim FirstName As String
        Dim LastName As String
    End Structure

    Public Sub GetEmployee(ByRef e As Employee)

        e.FirstName = "Mark"
        e.LastName = "Bertenshaw"

    End Sub

End Class

我使用REGASM / tlb为这个DLL创建一个类型库。

我还创建了一个测试VB6项目:

Private Sub Command_Click()

    Dim udtEmployee As TestDotNetStructures.Employee
    Dim oBoing As TestDotNetStructures.Boing

    oBoing.GetEmployee udtEmployee

End Sub

我成功地重复了你的错误。

然后我查看了REGASM生成的类型库(使用PowerVB类型库编辑器)。事实证明,为Employee类型创建的RECORD如下所示:

Record Employee
{
    LPWSTR FirstName
    LPWSTR LastName
}

包含LPWSTR的记录在COM方法中无效。 LPWSTR不是COM兼容类型。另一方面,BSTR肯定是。

修复方法是将编组属性添加到VB.NET代码中,告诉VB.NET将字符串作为BSTR传递:

Imports System.Runtime.InteropServices

<Microsoft.VisualBasic.ComClass()> Public Class Boing

    Public Structure Employee
        <MarshalAs(UnmanagedType.BStr)> Dim FirstName As String
        <MarshalAs(UnmanagedType.BStr)> Dim LastName As String
    End Structure

    Public Sub GetEmployee(ByRef e As Employee)

        e.FirstName = "Mark"
        e.LastName = "Bertenshaw"

    End Sub

End Class