Returning Multiple Results (UDT?) From An Interop Call - VB6 <--> VB.NET

耗尽温柔 提交于 2020-01-01 19:47:30

问题


I’d like an Interop user control (VB.NET) to return and to accept multiple values from a get/set call. I assumed a user defined type (UDT), would be the correct way but I keep getting a “Variable uses an Automation type not supported in Visual Basic” from the VB6 compile. How is passing multiple values between an interop control and the VB6 application done?

VB.NET (Interop) code, a control with a .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

Typical VB6 code:

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

回答1:


Have you considered passing your "stuff" as a dataset or using XML Serialization? I'm not real familiar with VB6, but I would think this would work. In order to pass a custom something between two of anything, they both have to be "aware" of that something.

You could also create a wrapper around the interop so that you can add a reference to your stuff to avoid code duplication. I can't say for sure, but I don't know of a way to just make your stuff passable between the two.




回答2:


The reason why you are getting the 'Variable uses an Automation type not supported in Visual Basic' error in VB6 is because the record created in the type library is not compliant with VB6. I created a new VB2005 project with COM Visible set to 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

I used REGASM /tlb to create a type library for this DLL.

I also created a test VB6 project:

Private Sub Command_Click()

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

    oBoing.GetEmployee udtEmployee

End Sub

I successfully repro'd your error.

I then looked at the type library generated by REGASM (using the PowerVB Type Lib Editor). It turns out that the RECORD created for the Employee type looked like this:

Record Employee
{
    LPWSTR FirstName
    LPWSTR LastName
}

A record containing LPWSTR is not valid as an argument in a COM method. LPWSTR is not a COM-compliant type. On the other hand, BSTR definitely is.

The fix is to add marshalling attributes to your VB.NET code to tell VB.NET to pass strings as 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


来源:https://stackoverflow.com/questions/10489368/returning-multiple-results-udt-from-an-interop-call-vb6-vb-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!