c++如何与C#交互 c++ C++/CLI入门教程【指南】

C++/CLI是微软提供的C++语法扩展,用于桥接原生C++与.NET(如C#),通过/ref class、gcroot等托管类型实现跨语言互操作,支持调用原生代码、暴露.NET接口及安全内存传递。

在 Windows 平台上,C++ 与 C# 交互最常用、最直接的方式是通过 C++/CLI(Common Language Infrastructure),它是微软为桥接原生 C++ 和 .NET(如 C#)设计的语言扩展。它不是“C++ 和 C# 混编”,而是让 C++ 代码能直接创建、调用、持有 .NET 对象,同时保留调用原生 C++ 函数的能力。

什么是 C++/CLI?它解决什么问题?

C++/CLI 是一种语法扩展(非标准 C++,需 /clr 编译开关),允许你在同一项目中:

  • 声明和使用托管类型(如 ref classgcroot)——可被 C# 直接引用
  • 调用 .NET Framework 或你自己写的 C# 类库(.dll)
  • 封装原有 C++ 代码(如算法、图像处理模块),暴露为简洁的 .NET 接口供 C# 调用
  • 在托管与非托管内存间安全传递数据(例如把 array^ 转为 unsigned char*

第一步:启用 C++/CLI 支持

在 Visual Studio 中新建一个 CLR 类库(.NET Framework) 项目(不是“控制台应用”或“动态链接库”)。关键设置:

  • 项目属性 → 常规 → “公共语言运行时支持” → 选择 “公共语言运行时支持 (/clr)”
  • 目标框架建议选 .NET Framework 4.7.2 或更高(兼容性好,避免 .NET Core/.NET 5+ 的限制)
  • 不要勾选“纯 MSIL 输出”,除非你完全不调用原生代码

写一个可被 C# 调用的 C++/CLI 包装器

假设你有一个原生 C++ 函数:
// NativeMath.h
int Add(int a, int b);

你想把它暴露给 C#。在 C++/CLI 项目中写:

// ManagedWrapper.h
#using
using namespace System;

public ref class MathWrapper
{
public:
    static int Add(int a, int b)
    {
        return ::Add(a, b); // 调用原生函数
    }
};

编译后生成 ManagedWrapper.dll,C# 项目右键“添加引用”→ 浏览到该 DLL 即可使用:
int r = MathWrapper::Add(3, 5); // 在 C# 中可直接调用(注意命名空间)

常见注意事项和避坑点

  • 不能跨 ABI 直接传 STL 容器:C# 看不到 std::vector,要用 array^List^
  • 字符串转换要显式:C# 的 String^ → C++ std::string 需用 marshal_as(头文件
  • 避免在托管类中直接存裸指针:用 gcroot 持有托管对象;原生资源用 RAII + 析构函数 + !ClassName()(终结器)管理
  • /clr 不支持 C++17 及以上全部特性:比如 structured bindings、constexpr if 在 /clr 下不可用;建议保持语法在 C++14 兼容范围内