在C#中调用C++代码时遇System.DllNotFoundException问题求助
解决C#调用C++ DLL时的System.DllNotFoundException问题
这个问题我之前做跨语言调用时也踩过坑,其实核心原因是C#运行时找不到你的C++ DLL文件——而且教程里不添加项目引用是对的,因为原生C++ DLL没法直接通过.NET的项目引用机制添加,咱们得从DLL的搜索路径、依赖匹配这些方面入手解决:
1. 保证DLL在C#程序的搜索路径内
Windows下.NET会按顺序在这些地方找DLL:
- 程序当前运行的目录(也就是C#项目的输出目录,比如
bin/Debug/net8.0) - Windows系统目录(System32/SysWOW64)
- 环境变量
PATH里的路径
最直接的解决方式:
- 手动把C++项目编译出的
SampleNativeLib.dll(注意区分x86/x64版本)复制到C#的输出目录里 - 更省心的办法:修改C项目的属性,把输出目录设置为和C#项目的输出目录一致(比如C#输出到
../CSharpApp/bin/Debug/x64,C就设成这个路径),这样每次编译C++都会自动把DLL放到正确位置
⚠️ 重点:平台必须完全匹配!C#项目的目标平台(右键项目->属性->生成->平台目标)要和C++ DLL的编译平台一模一样,比如C++编译的是x64,C#就不能选x86或Any CPU(Any CPU在64位系统会跑成x64,和x86 DLL不兼容)。
2. 检查DLL的依赖项是否完整
很多时候报错不是因为你的DLL找不到,而是它依赖的其他库缺失了——比如C编译时用到的VC运行时库(像vcruntime140.dll、msvcp140.dll这类)。
可以用VS自带的开发者命令提示符执行命令查看依赖:
dumpbin /dependents SampleNativeLib.dll
如果发现依赖的库不在搜索路径里,有两种解决方式:
- 安装对应的VC++ Redistributable包
- 修改C项目的运行时库设置为静态链接:右键C项目->属性->C/C++->代码生成->运行库,选择
Multi-threaded (/MT)(Release版)或Multi-threaded Debug (/MTd)(Debug版),这样编译出来的DLL会把依赖的运行时库打包进去,避免缺失问题。
3. 确认DllImport的配置正确
检查你的C#代码里的[DllImport]属性:
- 文件名要和C++编译出的DLL完全一致(Windows下大小写不敏感,但尽量严格匹配),比如:
[DllImport("SampleNativeLib.dll")] public static extern void YourNativeFunction(); - 如果DLL不在默认搜索路径,也可以指定绝对路径,但不推荐(移植性差):
[DllImport(@"C:\MyProjects\CppLib\x64\Debug\SampleNativeLib.dll")]
4. 验证C++函数是否正确导出
有时候DLL存在,但C++的函数名被**名字修饰(Name Mangling)**改变了,导致C#找不到对应的函数。可以用命令查看DLL的导出表:
dumpbin /exports SampleNativeLib.dll
如果看到导出的函数名是类似?YourNativeFunction@@YAXXZ这种奇怪的字符串,说明没禁用名字修饰。解决办法是在C++函数前加extern "C":
extern "C" __declspec(dllexport) void YourNativeFunction() { // 你的函数实现 }
这样导出的函数名就会保持原样,C#就能正确找到。
内容的提问来源于stack exchange,提问作者Petras




