最简可行路径是C#端DllImport声明必须与C++ DLL导出符号、调用约定、内存布局完全对齐:用extern "C"导出、显式指定CallingConvention.Cdecl、StructLayout(LayoutKind.Sequential, Pack=1)、字符串用MarshalAs正确封送。

怎么用 DllImport 加载 C++ DLL(最简可行路径)
能跑通的前提不是“写对 C++”,而是 C# 端的入口声明必须和 DLL 导出函数的符号、调用约定、内存布局完全对齐。很多失败直接卡在这一步。
实操建议:
- C++ DLL 必须用
extern "C"+__declspec(dllexport)导出函数,禁用 C++ name mangling;否则 C# 找不到符号 - C# 中
DllImport的EntryPoint要么省略(函数名一致),要么填 C++ 用dumpbin /exports xxx.dll查到的真实导出名(比如?Add@@YAHHH@Z就不行,得是ADD或add) - 显式指定
CallingConvention = CallingConvention.Cdecl—— Windows 上 C++ 默认是__cdecl,而 C#DllImport默认是StdCall,不匹配会栈错乱、程序崩溃 - DLL 文件必须放在 C# 程序运行时能搜到的位置:
exe同目录、PATH环境变量路径,或用SetDllDirectory提前设置
字符串传参为什么总崩?string 和 char* 怎么安全桥接
崩是因为 .NET 的 string 是托管对象,内存由 GC 管理,而 C++ 想直接读写裸指针。不加约束就传,大概率访问已释放内存或触发 GC 移动。
实操建议:
- 输入字符串:在
DllImport声明中加[MarshalAs(UnmanagedType.LPStr)](ANSI)或[MarshalAs(UnmanagedType.LPWStr)](Unicode),让 P/Invoke 自动做封送(marshal)并保证生命周期 - 输出字符串(C++ 写入缓冲区):不要返回
char*,改用StringBuilder入参,C++ 写入前确认长度够用,例如:void GetName(StringBuilder buf, int bufSize) - 绝对避免把
string直接转成IntPtr传给 C++ 作可写地址——GC 可能在任意时刻移动或回收它
struct 在 C# 和 C++ 之间怎么对齐才不乱码
结构体字段偏移不对齐,会导致 C# 读到的值全是错的,比如一个 int 变成负数、时间戳变零——这不是数据问题,是内存解释错误。
实操建议:
- C# 的
struct必须加[StructLayout(LayoutKind.Sequential, Pack = 1)],Pack = 1是关键,禁用编译器自动填充,和 C++ 默认行为对齐 - 所有字段类型必须一一对应:C++ 的
long在 Windows 是 4 字节,对应 C# 的int,不是long;bool在 C++ 是 1 字节,C# 要用byte或[MarshalAs(UnmanagedType.U1)] bool - 如果 C++ 用了
#pragma pack(4),C# 就得改成Pack = 4;别猜,用sizeof()在两边分别验证结构体大小是否一致
调试时提示 System.EntryPointNotFoundException 或 Attempted to read or write protected memory
前者是根本没找到函数,后者是找到了但内存操作越界了——两个错误原因完全不同,但新手常当成一类问题反复改调用方式。
实操建议:
-
EntryPointNotFoundException:用dumpbin /exports your.dll看真实导出名;检查DllImport的dllName是否拼错(注意扩展名要不要写);确认 CPU 架构一致(x64 程序不能加载 x86 DLL) -
AccessViolationException(即 protected memory):90% 是字符串或结构体封送错误,或 C++ 函数里写了野指针;打开 Visual Studio 的“启用本机代码调试”,让它能进 C++ 断点看哪一行崩的 - 加
[DllImport(..., SetLastError = true)],调用后立刻查Marshal.GetLastWin32Error(),有时能拿到更具体的系统级错误码
真正麻烦的从来不是“能不能调”,而是“调完数据对不对”——结构体字节对齐、字符串编码、内存所有权这些细节,漏掉一个,表现就是结果随机出错,很难复现。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











