编组 returns Double() 在 VBA 中使用的 .Net 函数

Marshalling a .Net function that returns Double() to consume in VBA

这是我在 .Net 中的函数:

<Runtime.InteropServices.ComVisibleAttribute(True)>
Public Function Unhex(hex As String) As Double()
    Dim GetArr As Double() = HexStringToDoubleArray(hex)
    Return GetArr
End Function

下面是我想在 VBA 中使用它的方式:

Dim ret() As Double
ret = LinkToComLib.Unhex("EDC531...")

有数百个关于如何将数组 传递到 .Net (eg), but the only one I found showing the opposite is this MS page 的示例,但它没有显示它在 VBA 上的使用(甚至 COM)端。也许我使用了错误的搜索词。无论如何:

  1. 我可以使用 MarshalAs 从 .Net 中导出 Double(),还是我需要使用 Marshal.Copy 或类似的东西(正如我怀疑的那样,因为它是受管理的)?
  2. 如果我确实必须 Copy,那么 return 类型是否正确 IntPtr
  3. 我认为 Dim ret() As Double 是指向 malloc 数组或 SAFEARRAY 的指针是否正确?这种情况下 VBA 中使用的类型是否正确?
  4. 在 VBA 中创建适当大小的数组(总是 492!),然后将其传递给函数是否有任何帮助?也许正在解除分配?

如果有人有指向此示例的指针 - 一个双精度(或整型)数组连同相应的 VBA 代码一起从 .Net 传递出去,我可能可以从那里获取它。但是,如果有人对上述问题有答案,VB.Net 或 C#,我将不胜感激。

您需要用 <MarshalAs(UnmanagedType.SafeArray)> 属性修饰 return。

VB.Net 示例:

Imports System.Runtime.InteropServices

<ComClass(ArrayExample.ClassId, ArrayExample.InterfaceId)> _
Public Class ArrayExample
    ' These  GUIDs provide the COM identity for this class  and its COM interfaces.
    Public Const ClassId As String = "e510d899-dad1-412b-94ea-6c726fe9f9da"
    Public Const InterfaceId As String = "ef3498f0-22b4-4c2a-aeb1-22936c9757eb"

    Public Function Unhex(hex As String) As <MarshalAs(UnmanagedType.SafeArray)> Double()
        Dim GetArr As Double() = {2.0R, 5.0R}
        Return GetArr
    End Function
End Class

VBA 用法:

Sub t()
   Dim c As ExampleComArrayReturn.ArrayExample
   Set c = New ExampleComArrayReturn.ArrayExample
   Dim arr() As Double
   arr = c.Unhex("AABB")
End Sub

编辑:忘记提及这使用 ComClassAttribute Class 让编译器为您的 class 生成接口。


编辑 2 以回应后续问题。

要调试 COM 库项目,请转到项目属性的“调试”选项卡。 Select "Start External Program" 并将其设置为 运行 Excel。您还可以在 "Command line Arguments" 中指定要打开的工作簿。现在,当您单击 "Start" 按钮时,将启动 Excel 并触发代码中的断点。


编辑 3:

要解决面向 .Net 3.5 的问题,您可以使用稍微不太方便的方法将调试器附加到 Excel 进程。如果您使用的是 VS2008,则上述方法将起作用。新的 VS 版本将需要附加到进程。可能有一种方法可以在 vproj.user 文件中指定此信息,但我还没有找到允许使用特定框架版本直接启动的神奇 属性 类型。

根据您的 VS 版本,"Attach To Process" 项将位于工具 (VS2013) 或调试 (VS2017) 菜单下,或者您可以使用快捷键 cntrl-alt-p。

显然启动 Excel 并加载您的工作簿。然后在 VS 中启动 Attach to Process 对话框。单击 "Select" 按钮,然后单击 "Debug these type" 单选按钮。 Select "Managed (v3.5, v3.0, v2.0) code" 类型并单击 "OK" 按钮。然后 select Excel 处理并点击 "Attach".