【问题标题】:Error Function or interface marked as restricted, or the function uses an Automation type not supported in Visual Basic in VB6错误 函数或接口标记为受限,或函数使用 VB6 中的 Visual Basic 不支持的自动化类型
【发布时间】:2020-05-02 09:56:13
【问题描述】:

我在 C# 中有一个必须在 VB 中初始化的数组。初始化时出现错误“函数或接口标记为受限,或函数使用 Visual Basic 不支持的自动化类型。”

C#.Net 代码:

public class InventoryMasterSearchSettings
{

   public string[] PrintLabelsIDetail { get; set; }

}

VB.Net 代码:

Public Property PrintLabelsIDetail() As String()                
    Get
        PrintLabelsIDetail = mInventoryMasterSearchSettings.PrintLabelsIDetail
    End Get
    Set(value As String())
        mInventoryMasterSearchSettings.PrintLabelsIDetail = value
    End Set
End Property

VB6

Public Sub ShowPrintLabels(invmast() As String, bShowAvailableInventoryOnlyPar As Boolean, Optional fCalledFromScreen As Form, Optional sVendorIDPar As String, Optional sUPCCodePar As String, Optional sInventoryDescriptionPar As String)
    Dim oInventoryMasterSearchSettings As New Shared_Interop.InventoryMasterSearchSettings
    oInventoryMasterSearchSettings.PrintLabelsIDetail = invmast           'error on PrintLabelsIDetail
End Sub

【问题讨论】:

  • 我认为您有一个未注册的旧 Active X 类。 Microsoft 在 2004 年左右淘汰了 Active X。如果将这些方法添加到机器注册表中,它们仍然可以使用。您似乎正在尝试将一个非常旧的 VB6 项目升级到 VB.Net 并收到此错误。
  • 我现在该如何解决这个问题?
  • 您必须找到包含 Shared_Interop 的 dll(库),然后注册该库。
  • Shared_Interop 是 C# 中的命名空间吗?

标签: c# .net vb.net vb6


【解决方案1】:

您确定 mInventoryMasterSearchSettings.PrintLabelsIDetail 的类型是标准数组吗? (不是集合,也不是 arraylist 类型)

你可以尝试两件事。

首先 - 使用编译器指令将数组强制为 COM“安全”数组。

Public Property PrintLabelsIDetail() As  <MarshalAs(UnmanagedType.SafeArray)> String()                
    Get
        PrintLabelsIDetail = mInventoryMasterSearchSettings.PrintLabelsIDetail
    End Get
    Set(value As String())
        mInventoryMasterSearchSettings.PrintLabelsIDetail = value
    End Set
End Property

因此,从消费的角度来看,上述内容可能有助于将字符串的 array() 编组为与 COM 端更兼容的东西。

另一个想法?您可以在返回之前对类型进行强制转换。

所以,这样说:

Public Property PrintLabelsIDetail() As <MarshalAs(UnmanagedType.SafeArray)> String()

    Get
        PrintLabelsIDetail = DirectCast(mInventoryMasterSearchSettings.PrintLabelsIDetail, String())
    End Get
    Set(value As String())
        mInventoryMasterSearchSettings.PrintLabelsIDetail = value
    End Set
End Property

此外,如果 string() 类型的数组未初始化,那么您可能需要确保在返回该数组之前已经发生。

作为一般规则,您可以将一个数组从 COM 端传递到 .net,但您必须将该数组作为 byref 而不是 byval 发送。

但是,您正在走另一条路。 .net --> COM 端。字符串类型的平面简数组通常可以转到 COM 端,即使没有上述 marshalas 编译器指令。

我会尝试一个或另一个想法,或者实际上就像我的第二个示例一样,尝试添加编组编译器指令和强制转换。

我的蜘蛛感觉提示 PrintLabelsIDetail 的数据类型是集合、iList 或 arrarylist 当它需要是字符串类型的 array() 时。所以,检查 PrintLabelsIDetail 的数据类型——我没有测试过,但我认为 COM 甚至不会喜欢用 arrayList 代替 Array。你最好先初始化数组,然后再通过 COM 桥发送它

编辑

我正在喝咖啡——directcast 可能会为您提供与 COM/ActiveX 兼容的数组,但我“认为”它可能会中断连接。 (VB6 方面将修改副本 - 它可能不会保留在 COM 对象成员中) - 所以尝试编译器指令而不使用 directcast 建议

【讨论】:

  • 编译器指令应该可以工作。您当然需要 Imports System.Runtime.InteropServices (vb.net)。如果没有导入互操作服务名称空间,我无法想象您取得了“任何”成功。因此,要使该编译器指令正常工作,您需要导入 Imports System.Runtime.InteropServices。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-29
  • 1970-01-01
  • 2014-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多