文章目录
-
-
- [1. DLL文件路径问题](#1. DLL文件路径问题)
- [2. 依赖的运行时库缺失](#2. 依赖的运行时库缺失)
- [3. 平台不匹配(x86/x64)](#3. 平台不匹配(x86/x64))
- [4. 导出函数名称不匹配](#4. 导出函数名称不匹配)
- [5. DLL文件损坏或权限问题](#5. DLL文件损坏或权限问题)
- [6. 运行时库冲突(MT/MD不匹配)](#6. 运行时库冲突(MT/MD不匹配))
- [7. 使用DLLImport时的常见错误](#7. 使用DLLImport时的常见错误)
- 总结步骤
-
在C#中调用C++动态库时出现System.DllNotFoundException
错误,即使添加了extern "C"
,仍可能有以下原因及解决方案:
1. DLL文件路径问题
C#默认在以下位置查找DLL(按优先级排序):
- 应用程序的
bin\Debug
或bin\Release
目录(输出目录)。 System32
或SysWOW64
目录(取决于平台)。- PATH环境变量中的路径。
解决方法:
-
将
TestDll.dll
直接复制到C#项目的输出目录(如bin\Debug
)。 -
在C#项目中设置DLL的"复制到输出目录"属性:
- 右键DLL文件 → 属性 → 复制到输出目录:始终复制。
-
或在代码中指定绝对路径(不推荐):
csharp[DllImport(@"C:\Full\Path\To\TestDll.dll")]
2. 依赖的运行时库缺失
C++ DLL可能依赖其他库(如MSVCRxxx.dll
、VCRUNTIMExxx.dll
或第三方DLL)。若这些依赖未正确部署,会导致加载失败。
解决方法:
- 使用工具检查依赖项 :
- 使用 Dependency Walker (旧版)或 Visual Studio的"依赖项查看器" (如
dumpbin /dependents TestDll.dll
)检查缺失的依赖。 - 用Everything直接搜索拖动到当前exe目录,全部拷贝过来肯定能运行。
- 删除某个DLL再看能否运行。
- 使用同样的步骤检查次级依赖的dll。
- 使用 Dependency Walker (旧版)或 Visual Studio的"依赖项查看器" (如
- 安装VC++运行时 :
- 如果依赖VC++运行时库(如
MSVCP140.dll
),安装对应版本的Visual C++ Redistributable。
- 如果依赖VC++运行时库(如
- 将依赖DLL与主DLL放在同一目录。
3. 平台不匹配(x86/x64)
如果C#项目与C++ DLL的编译平台(x86/x64)不一致,会导致无法加载。
解决方法:
- 确保C#项目的目标平台与DLL的平台一致:
- 右键C#项目 → 属性 → 生成 → 目标平台(选择x86或x64)。
- 如果DLL是64位的,C#项目必须设为
x64
;如果是32位的,设为x86
(不能使用Any CPU
)。
4. 导出函数名称不匹配
即使使用extern "C"
,仍需确保导出函数名称完全正确(包括大小写、修饰名)。
验证方法:
-
使用
dumpbin
工具查看导出的函数名:bashdumpbin /exports TestDll.dll
-
检查C#中
[DllImport]
的EntryPoint
名称是否与导出名称一致。
示例:
C++代码:
cpp
extern "C" __declspec(dllexport) int Add(int a, int b);
导出的函数名通常是Add
(无修饰),C#应声明为:
csharp
[DllImport("TestDll.dll")]
public static extern int Add(int a, int b);
5. DLL文件损坏或权限问题
- 确保DLL文件未被占用或损坏(尝试重新编译C++项目)。
- 检查文件权限:确保应用程序有权限读取DLL。
6. 运行时库冲突(MT/MD不匹配)
如果C++ DLL的运行时库设置(/MT
或/MD
)与C#环境不兼容,可能导致冲突。
解决方法:
- 在C++项目中统一使用
/MD
(动态链接运行时库):- 项目属性 → C/C++ → 代码生成 → 运行时库 → 选择
多线程DLL (/MD)
。
- 项目属性 → C/C++ → 代码生成 → 运行时库 → 选择
7. 使用DLLImport时的常见错误
-
确保函数调用约定一致(默认为
__stdcall
,但C++通常用__cdecl
)。csharp[DllImport("TestDll.dll", CallingConvention = CallingConvention.Cdecl)]
总结步骤
- 确认DLL位置:将DLL放在C#输出目录。
- 检查依赖项:确保所有依赖的DLL存在。缺少目标XXXdll的依赖,例如要用到的是A.dll,A.dll用到时需要添加B.dll动态库文件,在用到时需要两个dll同时存在。其中,B.dll导出有问题时通过dumpbin检查A.dll不能检查出来,需要进一步检查B.dll。
- 匹配平台:统一x86或x64。
- 验证导出函数 :使用
dumpbin
检查名称。 - 安装VC++运行时:确保目标机器已安装。
通过逐步排查上述问题,通常可以解决DllNotFoundException
。