通过VBA Declare语句导入C#自定义DLL到Excel时找不到入口点如何解决
问题原因
你遇到的Can't find DLL entry point报错核心是:默认编译的C#类库属于托管DLL,没有导出非托管风格的函数入口,而VBA中Declare语句的调用方式仅支持非托管(C/C++开发的原生DLL),无法直接识别托管DLL中的静态方法。
解决方案
有两种常用的可行方案,可根据场景选择:
方案1:将C#类库配置为COM可见(更适合Office集成场景)
不需要修改原有代码逻辑,只需要调整项目配置和调用方式:
- 步骤1:修改C#项目配置
- 右键C#项目 → 选择【属性】→ 切换到【应用程序】页 → 点击【程序集信息】→ 勾选【使程序集COM可见】
- 切换到【生成】页 → 勾选【为COM互操作注册】,同时将平台目标设置为和你使用的Excel位数一致:32位Excel选x86,64位Excel选x64,不要使用Any CPU
- 步骤2:调整C#代码,增加COM必要特性(建议加上避免GUID随机生成)
using System; using System.Runtime.InteropServices; namespace EchoText { [Guid("可通过VS工具栏的「创建GUID」工具生成固定GUID")] [ComVisible(true)] public class EchoTextTools { [ComVisible(true)] public string Concatenate(string text_1, string text_2) { return text_1 + text_2; } } }
注意:COM调用需要类有公共无参构造函数,且方法不要声明为static
- 步骤3:编译C#项目生成DLL,此时VS会自动完成COM组件注册
- 步骤4:修改VBA调用代码,不要用Declare语句,改为COM引用调用
- 打开VBA编辑器 → 点击顶部菜单【工具】→【引用】→ 找到你编译的
EchoText类库,勾选后确认 - 替换VBA代码为以下内容:
- 打开VBA编辑器 → 点击顶部菜单【工具】→【引用】→ 找到你编译的
Option Explicit Public Sub hello() Dim echoTools As Object Set echoTools = CreateObject("EchoText.EchoTextTools") MsgBox echoTools.Concatenate("Hello ", "World") Set echoTools = Nothing End Sub
方案2:导出非托管函数入口(无需COM注册)
如果不想做COM注册,可以用DllExport特性把C#方法导出为非托管入口:
- 步骤1:C#项目通过NuGet安装
UnmanagedExports包(VS2019及以上版本建议安装UnmanagedExports.Repack兼容性更好) - 步骤2:C#项目的平台目标必须明确指定为x86或x64,和Excel位数一致,不能用Any CPU
- 步骤3:修改C#代码,给要导出的方法加DllExport特性:
using System; using RGiesecke.DllExport; using System.Runtime.InteropServices; namespace EchoText { public class EchoTextTools { [DllExport("Concatenate", CallingConvention = CallingConvention.StdCall)] [return: MarshalAs(UnmanagedType.BStr)] public static string Concatenate([MarshalAs(UnmanagedType.BStr)] string text_1, [MarshalAs(UnmanagedType.BStr)] string text_2) { return text_1 + text_2; } } }
- 步骤4:编译项目后,生成的DLL就可以直接用你原来的VBA Declare代码调用,建议把DLL路径改为绝对路径避免工作目录异常:
Private Declare PtrSafe Function Concatenate Lib ThisWorkbook.Path & "\EchoText.dll" (ByVal text_1 As String, ByVal text_2 As String) As String
通用注意事项
- 两种方案都必须保证C#项目编译的平台和Excel位数完全一致,否则会出现加载失败的问题
- 如果部署到其他设备,方案1需要用管理员权限执行
regasm /codebase EchoText.dll完成COM注册,方案2不需要注册,直接携带DLL即可
内容的提问来源于stack exchange,提问作者Rui Monteiro
相关产品推荐
相关产品推荐

