当前位置: 首页 > news >正文

C#调用C++ 结构体方法

背景:接受的项目代码有一年了,对应C#调用C++中 结构体托管和非托管也有了一些自己的了解。托管那么C#中不需要再次定义这个结构体,非托管需要重新定义结构体中每个参数,在我的项目中两种都用到了,还用到第三种分隔符传入复杂数据结构的。

1、托管

使用 C++/CLI(托管 C++)桥接 C++ 和 C#

这种方式推荐用于调用复杂结构、类方法、STL 的情况。你可以:

  1. 在 C++/CLI 中封装 native C++ 结构体和函数。

  2. 在 C++/CLI 中创建托管类(public ref class)暴露给 C#。

  3. 在 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 接口

http://www.xdnf.cn/news/1001683.html

相关文章:

  • GitHub 上 PAT 和 SSH 的 7 个主要区别:您应该选择哪一个?
  • Transformer 与 XGBoost 协同优化的时间序列建模
  • LSTM助力迁移学习!深度学习架构性能提升,准确率达到99.91%!
  • TCN+Transformer+SE注意力机制多分类模型 + SHAP特征重要性分析,pytorch框架
  • 用于在多个远程计算机上求解的 Ansoft RSM 设置 - Windows
  • 实战案例-FPGA的JESD204B IP核配置详解
  • 【springboot组件开发】三方中间件自定义自动装载(rabbitmq/rocketmq/cmq)
  • 记录一次jenkins slave因为本地安装多个java版本导致的问题
  • stm32f103 标准库移植rt-thread nano
  • 学习笔记整理之状态图与状态图搜索
  • Windows 提权工具(“Potato“ 系列)用法指南
  • 火线、零线、地线 基础知识
  • 实现图片懒加载
  • 大话软工笔记—架构的概要设计
  • 【AS32系列MCU调试教程】基础配置:Eclipse项目与工具链的优化
  • SD-WAN优化云应用与多云架构访问的关键策略
  • 408考研逐题详解:2009年第39题
  • 深入探索IIC-OLED显示技术:嵌入式仿真平台如何重塑高校教学范式——深圳航天科技创新研究院技术赋能新一代工程教育
  • 观点 | 科技企业到了品牌建设的历史性窗口期
  • 界面开发框架DevExpress XAF实践:集成.NET Aspire后如何实现服务安排?
  • Kratos 与Golang Cms的关系
  • 深度学习环境搭建(pycharm+yolov5)
  • 【AWS入门】IAM多重身份验证(MFA)简介
  • 深度解析Git错误:`fatal: detected dubious ownership in repository` 的根源与解决方案
  • OpenAI API:LLM编程的事实标准(上)
  • R语言缓释制剂QBD解决方案之五
  • GitLab 拉取变慢的原因及排查方法
  • UE5 学习系列(九)光照系统介绍
  • linux中的locate命令
  • Vue3+TypeScript实现状态模式