C#调用C++ 结构体方法
背景:接受的项目代码有一年了,对应C#调用C++中 结构体托管和非托管也有了一些自己的了解。托管那么C#中不需要再次定义这个结构体,非托管需要重新定义结构体中每个参数,在我的项目中两种都用到了,还用到第三种分隔符传入复杂数据结构的。
1、托管
使用 C++/CLI(托管 C++)桥接 C++ 和 C#
这种方式推荐用于调用复杂结构、类方法、STL 的情况。你可以:
-
在 C++/CLI 中封装 native C++ 结构体和函数。
-
在 C++/CLI 中创建托管类(public ref class)暴露给 C#。
-
在 C# 中引用编译后的 C++/CLI DLL(.NET Assembly)。
示例结构
① Native C++ 结构体(NativeLib.h)
#pragma once struct MyStruct {int a;double b;double Sum() const {return a + b;} };
② C++/CLI 托管桥(ManagedBridge.cpp)
#include "NativeLib.h"public ref class MyStructWrapper { private:MyStruct* nativeStruct; public:MyStructWrapper(int a, double b) {nativeStruct = new MyStruct{ a, b };}~MyStructWrapper() {delete nativeStruct;}double Sum() {return nativeStruct->Sum();} };
③ C# 中使用
class Program {static void Main() {var wrapper = new MyStructWrapper(3, 4.5);double result = wrapper.Sum();Console.WriteLine($"Sum = {result}");} }
2、非托管
使用 P/Invoke 调用 C++ DLL(C 接口)
C++ 不支持直接导出类或结构体的方法给 P/Invoke,需要封装为 C 接口(extern "C"
),只传结构体作为参数。
🔧 示例结构体 + 导出方法(NativeLib.cpp)
extern "C" {struct MyStruct {int a;double b;};__declspec(dllexport) double Sum(MyStruct s) {return s.a + s.b;} }
C# 中 P/Invoke 调用
[StructLayout(LayoutKind.Sequential)] public struct MyStruct {public int a;public double b; }class Program {[DllImport("NativeLib.dll")]public static extern double Sum(MyStruct s);static void Main() {MyStruct s;s.a = 3;s.b = 4.5;double result = Sum(s);Console.WriteLine($"Sum = {result}");} }
🆚 比较总结
方法 | 优点 | 缺点 |
---|---|---|
C++/CLI | 支持类、方法、继承、STL等复杂结构 | 只能用于 Windows,编译设置复杂 |
P/Invoke | 跨平台,结构体/函数易绑定 | 不支持类方法,要手动封装为 C 接口 |