C#与C++交互开发系列(四):使用C++/CLI进行互操作

在这里插入图片描述

欢迎来到C#与C++交互开发系列的第四篇。在这篇博客中,我们将深入探讨使用C++/CLI进行互操作的方法和技巧。C++/CLI(Common Language Infrastructure)是C++与.NET框架之间的桥梁,能够让C++代码与托管代码无缝集成。

4.1 什么是C++/CLI?

C++/CLI是微软为C++添加的一组扩展,不仅允许C++代码调用.NET Framework的类库,还能让.NET语言如C#、F#和VB.NET调用C++的函数和类,使其能够与.NET平台互操作。通过C++/CLI,我们可以在同一个项目中使用托管代码(C#、VB.NET等)和非托管代码(原生C++),在需要高性能代码的场合可以使用C++,而在需要高级抽象和框架支持的地方则可以使用.NET,实现跨语言调用和数据交换。

C++/CLI的关键特性包括:

  • 支持托管和非托管代码混合编写
  • 能够直接访问.NET类库
  • 提供垃圾回收和内存管理功能

在这里插入图片描述

4.2 C++/CLI的基本语法

在这里插入图片描述
在编写C++/CLI代码时,我们需要理解一些基本的语法和关键字。

4.2.1 ref类和值类

在C++/CLI中,托管类(Managed Class)使用ref class关键字定义,而托管结构体(Managed Struct)使用value class定义。

// 托管类示例
public ref class MyClass
{
public:void MyMethod() {Console::WriteLine("Hello from MyClass");}
};// 托管结构体示例
public value class MyStruct
{
public:int x;int y;
};

4.2.2 gcnew关键字

在C++/CLI中,使用gcnew关键字来创建托管类型的实例,它类似于C#中的new,但是gcnew会触发垃圾回收机制,从而不需要手动管理内存。

MyClass^ myClassInstance = gcnew MyClass();
myClassInstance->MyMethod();

4.2.3 内存管理

C++/CLI中的托管类型由.NET的垃圾回收器(GC)自动管理,而非托管类型仍需手动管理内存。使用C++/CLI可以简化内存管理,减少内存泄漏的风险。使得开发者能够专注于业务逻辑而不是低级的资源管理。

4.3 创建简单的C++/CLI项目

在这里插入图片描述

为了理解C++/CLI的基本用法,我们来创建一个简单的C++/CLI项目,并实现一个基础的互操作示例。

Step 1: 创建C++/CLI项目

  1. 打开Visual Studio,创建一个新的项目。
  2. 选择 C++ 动态库 模板,并命名为MyCppCliLibrary
  3. 确保项目类型设置为DLL
    在这里插入图片描述
    4.公共语言运行时选择,.NET 运行时支持(/clr:netcore)和.NET目标框架版本选择.NET 8.0
    在这里插入图片描述

Step 2: 编写C++/CLI代码

MyCppCliLibrary项目中,添加以下代码:

// MyCppCliLibrary.h
#pragma onceusing namespace System;namespace MyCppCliLibrary {public ref class Calculator{public:int Add(int a, int b) {return a + b;}};
}

这个简单的示例定义了一个Calculator类,包含一个Add方法,用于计算两个整数的和。

Step 3: 编译C++/CLI项目

编译项目生成MyCppCliLibrary.dll文件。

4.4 C++/CLI与C#的互操作

接下来,我们在C#项目中调用这个C++/CLI库。创建一个新的C#控制台应用程序,并添加对MyCppCliLibrary.dll的引用。

Step 4: 在C#中调用C++/CLI库

在C#项目中添加以下代码:

using System;
using MyCppCliLibrary;class Program
{static void Main(){Calculator calculator = new Calculator();int result = calculator.Add(3, 4);Console.WriteLine($"3 + 4 = {result}");}
}

运行程序,输出结果3 + 4 = 7
在这里插入图片描述

4.5 性能比较和优化

虽然C++/CLI提供了便利的互操作,但性能方面可能不如纯C++或纯C#代码。性能优化通常涉及减少托管和非托管代码间的边界跨越,因为每次跨越都会产生一定的开销。以下是一些性能优化的建议:

  1. 减少托管和非托管代码的切换:频繁切换会带来额外的性能开销,尽量将相关操作集中在一起。
  2. 使用本地变量:避免在托管堆和非托管堆之间频繁分配和释放内存。
  3. 合理使用pin_ptr:在需要将托管数组传递给非托管代码时,使用pin_ptr可以避免内存复制,提高性能。

4.6 代码示例

为了展示更复杂的互操作场景,我们来看一个包含托管数组和非托管指针的示例。

Step 1: 更新C++/CLI代码

// MyCppCliLibrary.h
#pragma onceusing namespace System;namespace MyCppCliLibrary {public ref class Calculator{public:int Add(int a, int b) {return a + b;}void MultiplyArray(array<int>^ managedArray, int factor) {pin_ptr<int> pinnedArray = &managedArray[0];int* nativeArray = pinnedArray;for (int i = 0; i < managedArray->Length; i++) {nativeArray[i] *= factor;}}};
}

Step 2: 编译C++/CLI项目

编译项目生成MyCppCliLibrary.dll文件。

Step 3: 在C#中调用更新后的C++/CLI库

在C#项目中添加以下代码:

using System;
using MyCppCliLibrary;class Program
{static void Main(){Calculator calculator = new Calculator();// 调用Add方法int sum = calculator.Add(3, 4);Console.WriteLine($"3 + 4 = {sum}");// 调用MultiplyArray方法int[] array = { 1, 2, 3, 4, 5 };calculator.MultiplyArray(array, 2);Console.WriteLine("Array after multiplication:");foreach (int value in array){Console.WriteLine(value);}}
}

运行程序,输出结果:

在这里插入图片描述

4.6 总结

在这篇博客中,我们介绍了使用C++/CLI进行C#与C++互操作的方法和技巧。通过C++/CLI,我们可以轻松地在C#中调用C++代码,实现跨语言的功能集成。C++/CLI是一个强大的工具,它融合了C++的强大功能和.NET的灵活性,使得在不同语言环境下的代码集成变得更加容易。不过,在设计系统架构时,应当考虑到性能和维护性的平衡,以决定何时使用C++/CLI进行互操作。我们还讨论了性能优化的一些建议。在下一篇博客中,我们将探讨更高级的P/Invoke技巧,进一步提升我们的互操作能力。

4.7 参考

  • 使用 C++/CLI 进行 .NET 编程

  • C++/CLI基本语法和最佳实践

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/48461.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【源码阅读】Sony的go breaker熔断器源码探究

文章目录 背景源码分析总结 背景 在微服务时代&#xff0c;服务和服务之间调用、跨部门调用都是很常见的事&#xff0c;但这些调用都存在很多不确定因素&#xff0c;如核心服务A依赖的部门B服务挂掉了&#xff0c;那么A本身的功能将会受到直接的影响&#xff0c;而这些都会影响…

GaussianPro使用笔记

1. 介绍 GaussianPro: 3D Gaussian Splatting with Progressive Propagation 3D高斯分布(3DGS)最近以其高保真度和效率彻底改变了神经渲染领域。然而&#xff0c;3DGS在很大程度上依赖于运动结构&#xff08;SfM&#xff09;技术生成的初始化点云。当处理不可避免地包含无纹理…

<数据集>手势识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;2400张 标注数量(xml文件个数)&#xff1a;2400 标注数量(txt文件个数)&#xff1a;2400 标注类别数&#xff1a;5 标注类别名称&#xff1a;[fist, no_gesture, like, ok, palm] 序号类别名称图片数框数1fist597…

Pycharm 和虚拟环境的那些事?

背景: 我既有 python 又有Anaconda Pycharm新建虚拟环境: 只说两种方式 通过Virualenv Environment新建: 这里我们勾选上 Make available to all projects ,之后点击&#x1f197; 然后可以发现只有非常少的包,因为没有勾选继承 编译器的包 创建的虚拟环境一般目录如下&…

Sparse4D-v3:稀疏感知的性能优化及端到端拓展

极致的感知性能与极简的感知pipeline一直是牵引我们持续向前的目标。为了实现该目标&#xff0c;打造一个性能优异的端到端感知模型是重中之重&#xff0c;充分发挥深度神经网络数据闭环的作用&#xff0c;才能打破当前感知系统的性能上限&#xff0c;解决更多的corner case&am…

下载最新版Anaconda、安装、更换源、配置虚拟环境并在vscode中使用

文章目录 进入官网进入下载页安装更换源配置虚拟环境env安装包requests在vscode中使用虚拟环境 进入官网 https://repo.anaconda.com/ 或进入清华大学下载 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 进入下载页 安装 更换源 查看已经存在的镜像源 bash cond…

物联网在养殖业领域的应用——案例分析

作者主页: 知孤云出岫 目录 作者主页:物联网在养殖业领域的应用——案例分析背景技术架构硬件设置连接多种传感器到微控制器 代码实现1. Arduino代码&#xff1a;采集多种传感器数据并上传到Thingspeak2. Python代码&#xff1a;从Thingspeak获取数据并进行综合分析和可视化 …

大模型学习笔记十二:AI产品部署

文章目录 一、如何选择GPU和云服务器厂商&#xff0c;追求最高性价比1&#xff09;根据场景选择GPU2&#xff09;训练或微调所需显卡&#xff08;以Falcon为例子&#xff09;3&#xff09;服务器价格计算器 二、全球大模型了解1&#xff09;llm所有模型2&#xff09;模型综合排…

WSL2 Centos7 Docker服务启动失败怎么办?

wsl 安装的CentOS7镜像,安装了Docker之后,发现用systemctl start docker 无法将docker启动起来。 解决办法 1、编辑文件 vim /usr/lib/systemd/system/docker.service将13行注释掉,然后在下面新增14行的内容。然后保存退出。 2、再次验证 可以发现,我们已经可以正常通过s…

offer题目51:数组中的逆序对

题目描述&#xff1a;在数组中的两个数字&#xff0c;如果前面一个数字大于后面的数字&#xff0c;则这两个数字组成一个逆序对。输入一个数组&#xff0c;求出这个数组中的逆序对的总数。例如&#xff0c;在数组{7,5,6,4}中&#xff0c;一共存在5个逆序对&#xff0c;分别是(7…

给Wordpress添加评分功能到评论表单

今天要 给你的 Wordpress 添加评分功能到评论表单 吗&#xff1f; 评分功能效果图 什么类型的网站需要评分&#xff1f; 资源站教程站其他&#xff0c;我也没想到。。。 但我这个网站&#xff0c;因为是电影类的网站&#xff0c;好像还是有点需要的&#xff0c;所以&#xf…

针对汽车应用而设计的SCT4026D、SCT4062K、SCT3105K、SCT3080A、SCT3060A全新系列碳化硅 (SiC) MOSFET

全新系列碳化硅 (SiC) MOSFET SCT4026DWAHRTL SCT4062KWAHRTL SCT3105KRC15 SCT3080ALHRC11 SCT3080ARC15 SCT3060ARC15 ——明佳达 AEC-Q101 SiC功率MOSFETs是汽车和开关电源的理想选择。SiC功率MOSFETs可以提高开关频率&#xff0c;减少所需的电容、电抗器和其他元件的体积…

【RAG探索第4讲】KG+RAG丨基于知识图谱优化大型语言模型方法

原文链接&#xff1a;【RAG探索第4讲】KGRAG丨基于生物医学知识图谱优化的大型语言模型提示生成方法 一、现有问题&#xff1a; LLMs在处理特定领域或高度专业化查询时缺乏专业知识&#xff0c;导致回答不够准确和可靠。 LLMs可能会产生事实错误&#xff08;即幻觉&#xff0…

【计算机视觉】siamfc论文复现

什么是目标跟踪 使用视频序列第一帧的图像(包括bounding box的位置)&#xff0c;来找出目标出现在后序帧位置的一种方法。 什么是孪生网络结构 孪生网络结构其思想是将一个训练样本(已知类别)和一个测试样本(未知类别)输入到两个CNN(这两个CNN往往是权值共享的)中&#xff0…

深入理解PHP基础【代码审计实战指南】

文章目录 基础语法单双引号的区别前后端分离数据类型PHP常量函数var_dump函数count函数print_r函数**readfile&#xff08;&#xff09;函数****file_get_contents()函数****file_put_contents()函数**header函数fopen函数fread 函数rename函数copy&#xff08;&#xff09;函数…

OCR识别采购单小程序管理助手

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

Qt开发网络嗅探器01

引言 随着互联网的快速发展和普及&#xff0c;人们对网络性能、安全和管理的需求日益增 长。在复杂的网络环境中&#xff0c;了解和监控网络中的数据流量、安全事件和性能 问题变得至关重要。为了满足这些需求&#xff0c;网络嗅探器作为一种重要的工具被 广泛应用。 网络嗅探…

【Godot4.2】SVGParser - SVG解析器函数库

概述 这是一个基于GDScript内置XMLParser编写的简易SVG文件解析函数库。 目的就是可以将SVG文件解析为GDSCript可以处理的字典或DOM形式&#xff0c;方便SVG渲染和编辑。 目前还只是一个简易实现版本。还需要一些改进。 函数库源码 # # 名称&#xff1a;SVGParser # 类型…

AI算法23-决策树ID3算法Iterative Dichotomiser 3 | ID3

目录 决策树ID3算法概述 决策树ID3算法简介 决策树ID3算法的原理 决策树ID3算法的核心 决策树ID3算法的本质 决策树ID3算法的基本流程 决策树ID3算法计算过程 步骤1 步骤2 步骤3 决策树ID3算法的代码实现 决策树ID3算法的优缺点 优点 缺点 决策树ID3算法的应用场…

ue5笔记

1 点光源 聚光源 矩形光源 参数比较好理解 &#xff08;窗口里面&#xff09;环境光混合器&#xff1a;快速创造关于环境光的组件 大气光源&#xff1a;太阳光&#xff0c;定向光源 天空大气&#xff1a;蓝色的天空和大气 高度雾&#xff1a;大气下面的高度感的雾气 体积…