这是我在.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)方面使用。也许我使用了错误的搜索词。无论如何:
MarshalAs
从.Net导出Double()
,还是需要使用Marshal.Copy
或类似内容(我怀疑,因为它是管理的)?Copy
,那么正确的返回类型是IntPtr
吗?Dim ret() As Double
是指向malloc的数组或SAFEARRAY的指针是正确的吗?在这种情况下,这是在VBA中使用的正确类型吗?如果有人有一个指向这个例子的指针 - 一个双重(或整数)数组与相应的VBA代码一起从.Net传出,我可以从那里拿走它。但如果有人对上述内容,VB.Net或C#的答案如愿,我会很感激。
答案 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并触发代码中的断点。
编辑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;。