我在这里遇到一个小问题,需要你帮忙.
我有一个通过COM互操作公开的C#DLL.它工作正常,但显然C#interop对象的部署是一场灾难,每次更新DLL时都需要重新计算.
所以我想知道如何使用这个C#DLL中的函数,如下所示:或者我可以通过将DLL和电子表格放在一起来调用函数.
Declare Function getString Lib "<PATH of my DLL>" () as string
sub test()
range("A1").value = getString
End Sub
Run Code Online (Sandbox Code Playgroud)
语法可能有误.
Rob*_*cke 16
你可以这样做,但你必须意识到VBA和.Net的区别.
首先,您必须创建一个实际的DLL(.Net程序集不是),为此,使用此项目模板.然后,你必须知道如何编组东西.
VBA仅支持stdcall作为调用约定,它不能真正处理DLL函数的Unicode.这本身并不错,因为.Net中String的默认封送是VBA所期望的(指向Ansi char的指针).此外,stdcall是我用于导出的默认调用约定.
我将重用我最近为另一个SO线程创建的示例:
把它放在你使用我的模板创建的项目中:
[ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)]
public class Sample
{
public string Text
{
[return: MarshalAs(UnmanagedType.BStr)]
get;
[param: MarshalAs(UnmanagedType.BStr)]
set;
}
[return: MarshalAs(UnmanagedType.BStr)]
public string TestMethod()
{
return Text + "...";
}
}
static class UnmanagedExports
{
[DllExport]
[return: MarshalAs(UnmanagedType.IDispatch)]
static Object CreateDotNetObject(String text)
{
return new Sample { Text = text };
}
}
Run Code Online (Sandbox Code Playgroud)
这是如何从VBA调用它:
Declare Function CreateDotNetObject Lib "The full path to your assembly or just the assembly if it is accessible from Excel" _
(ByVal text As String) As Object
Sub test()
Dim instance As Object
Set instance = CreateDotNetObject("Test 1")
Debug.Print instance.Text
Debug.Print instance.TestMethod
instance.text = "abc 123" ' case insensitivity in VBA works as expected'
Debug.Print instance.Text
End Sub
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22866 次 |
| 最近记录: |