使用 UnmanagedExports 包 [DllExport] 在 VBA 中调用 C# DLL 触发 "Can't Find DLL Entry Point" 错误

Using UnmanagedExports Package [DllExport] to call C# DLL in VBA Triggers "Can't Find DLL Entry Point" Error

我正在使用 Robert Giesecke's Unmanaged Exports 包来访问 Excel VBA 中的 c# dll。我遵循了几个示例并继续得到 运行 时间错误 453:“在 myDllName.dll 中找不到入口点 MyDLLFunction”

我在使用 64 位 Excel 的 64 位机器上,正在为 x64 打包 dll。

我在 Visual Studio 2022 年工作,并尝试在 .NET 6.0 和 .Net Framework 4.7.2 中准备 dll。

这是我导出的 class:

namespace MyNamespace
{
    public static class UnmanagedExports
    {
        //entry point for dll
        static UnmanagedExports()
        {
            //nothing
        }


        [DllExport("HelloWorld", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl)]
        public static string HelloWorld()
        {
            return "Hello World";
        }

        [DllExport("MyDLLFunction", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl)]
        [return: MarshalAs(UnmanagedType.IDispatch)]
        static object MyDLLFunction()
        {
            return new InnerNamespace.MyCsharpClass();
        }
    }

}

然后这是我的另一个 C#:

namespace MyNamespace.InnerNamespace
{
    [ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)]
    public class MyCsharpClass
{
        [return: MarshalAs(UnmanagedType.BStr)]
        public async Task<string> InnerFunction(string LookupType, string LookupNumber)
        {
            object Response = await GetResponseAsync(LookupType, LookupNumber);
            string ResultAsString = Response.ToString();
            return ResultAsString;
        }
}

在Excel VBA:

Private Declare PtrSafe Function AddDllDirectory Lib "kernel32" (ByVal lpLibFileName As String) As Integer
Public Declare PtrSafe Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As LongPtr
Public Declare PtrSafe Function MyDLLFunction Lib "C:\my\long\path\to\my\project\bin\x64\Debug\net472\myDllName.dll" () As Object

Sub Test()
  Dim mObj As Object
  Set mscObj = MyDLLFunction()  //run time error here <- can't find entry point
End Sub

我关注了 但它不起作用。

我用谷歌搜索并测试了各种配置,但一直无法解决“找不到入口点”的错误。

我相信它是固定的。我终于能够在 dumpbin /exports 输出中看到导出的函数。我认为需要做几件事来解决这个问题。希望这对以后的人有所帮助。

打包未更新 - 尝试旧版本的 VS

根据包的年龄,我怀疑它在 VS2022 中没有合作,所以,我:

  • 在 Visual Studio 2015 年创建项目(对比我使用的 VS2022)
  • 从头开始重建项目并添加对新项目的引用,而不是尝试在 VS2015 中打开旧项目

DllExportAppDomainIsolatedTask 错误

然后,项目无法构建,它一直抛出错误:

The "DllExportAppDomainIsolatedTask" task failed unexpectedly.

基于this answer 我:

  • 已安装适用于 VS2015 的 Microsoft 构建工具
  • 安装 .NET 3.5 并手动添加 Microsoft.Build.Tasks.v3.5 作为对我的项目的引用,方法是在安装 .NET3.5 后浏览到它的位置

但我一直收到同样的错误。然后我通过更改设置来增加调试输出:Project>Properties>Build>Errors and Warnings>Warning Level to 4.

通过调试日志我发现了 UnmanagedExports 包中的几行引用了项目平台、框架路径、库工具路径、工具 dll 路径等。在该部分我发现: System.ArgumentException: Requested value 'Version47' was not found.

我的目标是 .NET Framework 4.7.2,所以我将项目降级为目标 .NET Framework 4.5,删除了 bin/obj 文件夹内容并重建了项目。然后,运行 dumpbin /exports 展示了我的 HelloWorld 函数!

似乎该包与 .NET Framework 4.7.2 不兼容。