编组 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)端。也许我使用了错误的搜索词。无论如何:
- 我可以使用
MarshalAs
从 .Net 中导出 Double()
,还是我需要使用 Marshal.Copy
或类似的东西(正如我怀疑的那样,因为它是受管理的)?
- 如果我确实必须
Copy
,那么 return 类型是否正确 IntPtr
?
- 我认为
Dim ret() As Double
是指向 malloc 数组或 SAFEARRAY 的指针是否正确?这种情况下 VBA 中使用的类型是否正确?
- 在 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".
这是我在 .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)端。也许我使用了错误的搜索词。无论如何:
- 我可以使用
MarshalAs
从 .Net 中导出Double()
,还是我需要使用Marshal.Copy
或类似的东西(正如我怀疑的那样,因为它是受管理的)? - 如果我确实必须
Copy
,那么 return 类型是否正确IntPtr
? - 我认为
Dim ret() As Double
是指向 malloc 数组或 SAFEARRAY 的指针是否正确?这种情况下 VBA 中使用的类型是否正确? - 在 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".