.Net互操作-C++Interop (C++/CLI) 在构建大规模 .NET 系统与原生 C++/Win32 库的互操作边界时,虽然 P/Invoke 能够处理多数扁平化的 C 样式导出函数,但面对以下场景时会显得力不从心:深度面向对象集成:需要直接继承非托管 C++ 类,或者在托管端直接复用复杂的 C++ 原生类和结构体。高频低开销调用:P/Invoke 在每次调用时都会经历严格的封送层检查与切换。而 C++ Interop (C++/CLI) 允许托管代码与原生 C++ 代码直接“同文件混合编写”(又称 It Just Works 机制),能够实现无缝的机器码与托管码混合,大幅降低数据转换开销。异常完美传递:能够直接捕获原生 C++ 异常,并在互操作层包装为托管异常传给 C#,避免了 P/Invoke 难以获取非托管底层崩溃细节的弊端。托管扩展与 CLR 类型体系在 C++/CLI 环境中,编译器通过一套扩展关键字将 .NET 的 CLR 类型体系引入到 C++ 中。非托管的原生实体必须进行正确的包装才能对 C# 导出。基础概念与映射关系托管类与结构体:使用ref class或ref struct声明。它们分配在托管堆(Managed Heap)上,其生命周期由 .NET GC 自动管理。托管枚举:使用enum class定义。跟踪句柄(^):对应 C# 中的引用符号。例如String^对应 C# 中的string。它不是一个物理内存指针,而是受 GC 变址追踪的托管引用。跟踪引用(%):类似于 C++ 中的原生引用,用于追踪托管堆上的句柄,在互操作的方法形参中充当out或ref关键字的角色。常量声明:原生 C++ 的const无法跨 CLR 边界提供给 C#,必须使用literal关键字声明托管常量。// 基础类型与引用声明String^strMessage=nullptr;// 托管字符串,使用 nullptr 初始化arrayint^nArray=gcnewarrayint(5);// 托管一维数组,使用 gcnew 分配intnValue=100;int%nTrackRef=nValue;// 跟踪引用literalintMaxBufferLength=256;// 跨语言可读的托管常量复杂结构体的托管包装如果需要定义一个能够无缝传递给原生 C++ 函数的托管结构体,必须通过StructLayout属性严格控制其字段对齐。原生 C++ 结构体原型:#pragmapack(push,MyPack_H,4)structCPPStruct{BOOL bValid;DWORD nCount;LARGE_INTEGER liNumber;WCHAR wzName[10];BYTE byBuff[100];};#pragmapack(pop,MyPack_H)对应的 C++/CLI 托管实体封装:usingnamespaceSystem;usingnamespaceSystem::Runtime::InteropServices;[StructLayout(LayoutKind