【问题标题】:Returning Multiple Results (UDT?) From An Interop Call - VB6 <--> VB.NET从互操作调用返回多个结果(UDT?) - VB6 <--> VB.NET
【发布时间】:2012-05-16 09:23:05
【问题描述】:

我想要一个 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

【问题讨论】:

  • 您可能需要将属性应用到结构定义以使其可用。或者,您是否尝试过使用类而不是结构?
  • 结构是 COM 中的一个问题,它们具有非常依赖于编译器/硬件的布局。 IRecordInfo 接口几乎不支持它们,通常需要在类型库中声明结构。值得注意的是,当被要求处理公共 UDT 时,VB6 构建系统非常糟糕。只需将 Employee 声明为 [ComVisible] 接口 + 类即可避免此类麻烦。
  • 你能提供一些代码来演示这个吗?

标签: vb.net vb6 com-interop


【解决方案1】:

在 VB6 中出现“Variable uses an Automation type not supported in Visual Basic”错误的原因是在类型库中创建的记录不符合 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

【讨论】:

    【解决方案2】:

    您是否考虑过将“资料”作为数据集传递或使用 XML 序列化?我对VB6并不熟悉,但我认为这会起作用。为了在两个事物之间传递自定义事物,它们都必须“意识到”该事物。

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

    【讨论】:

    • 我唯一的经验是 .NET 中的 Office 互操作。如果我在这里说得离题,请告诉我。 =)
    • 与此同时,我正在使用一种廉价的解决方法:我正在返回一个包含所有信息的字符串,然后在另一端使用拆分来解压缩它。它在两个方向都有效。对于临时解决方案来说还不错,但我宁愿采用更强大的方法。
    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 2012-02-29
    • 1970-01-01
    • 2023-03-04
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多