编组一个返回Double()以在VBA中使用的.Net函数

时间:2018-02-13 18:54:42

标签: vb.net marshalling com-interop

这是我在.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)的示例,但我发现显示相反的唯一一个是this MS page,并且它没有显示它在VBA(甚至COM)方面使用。也许我使用了错误的搜索词。无论如何:

  1. 我可以使用MarshalAs从.Net导出Double(),还是需要使用Marshal.Copy或类似内容(我怀疑,因为它是管理的)?
  2. 如果我必须Copy,那么正确的返回类型是IntPtr吗?
  3. 我认为Dim ret() As Double是指向malloc的数组或SAFEARRAY的指针是正确的吗?在这种情况下,这是在VBA中使用的正确类型吗?
  4. 在VBA中创建具有适当大小(它总是492!)的数组,然后以任何方式将其传递给函数帮助?也许解除了?
  5. 如果有人有一个指向这个例子的指针 - 一个双重(或整数)数组与相应的VBA代码一起从.Net传出,我可以从那里拿走它。但如果有人对上述内容,VB.Net或C#的答案如愿,我会很感激。

1 个答案:

答案 0 :(得分:1)

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

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让编译器为你的类生成接口。

编辑2以回应后续问题。

要调试COM库项目,请转到项目属性的“调试”选项卡。选择&#34;启动外部程序&#34;并将其设置为运行Excel。您还可以在&#34;命令行参数&#34;中指定要打开的工作簿。现在当你点击&#34;开始&#34;按钮,将启动Excel并触发代码中的断点。

Setup Run External Application

编辑3:

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

根据您的VS版本,&#34;附加到流程&#34; item将位于Tools(VS2013)或Debug(VS2017)菜单下,或者您可以使用快捷键cntrl-alt-p。

显然启动Excel并加载您的工作簿。然后在VS中启动“附加到进程”对话框。点击&#34;选择&#34;按钮,然后单击&#34;调试这些类型&#34;单选按钮。选择&#34;托管(v3.5,v3.0,v2.0)代码&#34;输入并单击&#34;确定&#34;按钮。然后选择Excel流程并单击&#34;附加&#34;。

enter image description here