基于C++/CLI实现C#调用C++类对象过程中的注意事项

news2025/2/27 2:49:28

目录

  • 一、基于C++/CLI 的调用原理
  • 二、注意事项
    • 如何基于VS2010完成上述一系列开发过程
      • 1、生成C++应用程序(非托管代码)
      • 2、基于C++/CLI生成托管代码
      • 3、C#调用
  • 三、C++/CLI与COM组件对比

一、基于C++/CLI 的调用原理

C++/CLI (Common Language Infrastructure)是一种特殊的 C++ 语言,它支持在 .NET 平台上进行开发和编译。C++/CLI 可以让开发人员使用 C++ 语言来编写 .NET 应用程序,并且可以直接访问和使用 .NET 框架中的类库。其支持托管代码和非托管代码:C++/CLI 中既可以编写非托管代码,也可以编写托管代码。这使得开发人员可以利用现有的 C++ 代码库,并将其集成到 .NET 应用程序中。

托管代码是指运行在 .NET 运行时(Common Language Runtime)中的代码。托管代码是由编译器生成的,它们包含了一些元数据信息,这些信息可以被 .NET 运行时用来管理代码的执行、内存分配、垃圾回收等操作。

非托管代码是指不运行在 .NET 运行时中的代码。这些代码通常是使用 C 或 C++ 等语言编写的,并且直接访问计算机的硬件资源和操作系统 API。非托管代码不包含元数据信息,也不依赖于 .NET 运行时,因此它们无法直接与托管代码进行交互。(即待调用的C++ 应用程序)

因此我们的思路为:通过C++/CLI 的委托代码调用C++应用程序(非委托代码),从而生成.NET应用,实现基于C#的访问。
其中,每个环节都是利用动态链接库(.dll)交互实现。

二、注意事项

如何基于VS2010完成上述一系列开发过程

1、生成C++应用程序(非托管代码)

这个就是我们需要被调用的应用程序,根据各个项目需求自行设计。需要注意,编译生成的文件需改成.dll格式而非传统的.exe控制台,如下所示:
在这里插入图片描述

2、基于C++/CLI生成托管代码

这一步摸索了一段时间,感觉和编译器的版本也有关系,VS2010确实有点老了,存在不便。因此,本人详细罗列了相关操作流程。

首先,我们需要新建一个CLR(Common Language Runtime)环境。这里说明下:C++/CLI 和CLR关系,前者是针对 .NET 平台而设计的一种编程语言,可以方便地将 C++ 代码与 .NET 技术集成在一起,而后者则是 .NET 平台的核心组件,提供了运行时环境和基础设施。

选中**”类库“**!!!同时注意所使用的.NET FrameWork版本。
(可能是本人操作问题,之前尝试选中的是”CLR空项目“,结果出现C#无法访问其空间域。)
在这里插入图片描述

完成后,为项目添加C++应用程序编译生成的dll引用
在这里插入图片描述

再将C++应用程序代码作为现有项添加至”源文件“,并将其路径添加至包含目录。
在这里插入图片描述
顺道给个代码实现demo:

// myCLR.h

#pragma once
#include "myTest.h"//C++应用程序 头文件
#include "string.h"
#include <msclr/marshal_cppstd.h>

using namespace System;
using namespace msclr::interop;

namespace myCLR {
	//ref class 作为委托类,从而使得C#可对Person_CLI进行访问
	public ref class Person_CLI
	{
	public:
		void initPersonClass();
		void setPersonInfo(System::String^ name,int age,double height);
	private:
		Person *_p;//C++应用程序 声明Person类对象
		string convertToStd(System::String^ str);
	};
}

// 这是主 DLL 文件。

#include "stdafx.h"
#include "myCLR.h"


void myCLR::Person_CLI::initPersonClass(){
    //new 
	_p=new Person();
}
void myCLR::Person_CLI::setPersonInfo(System::String^ name,int age,double height){
	//访问类的成员函数
	string strName=convertToStd(name);
	_p->init(strName,age,height);
	_p->showInfo();
}

//System::String^ str 转为 string
//因为C#只有System::String^类型, 与C++应用程序函数的参数类型string  不兼容
string myCLR::Person_CLI::convertToStd(System::String^ str){
	marshal_context context;
    return context.marshal_as<std::string>(str);
}

3、C#调用

将添加C++/CLI生成的DLL,即可访问
在这里插入图片描述

using System;
using System.Runtime.InteropServices;
using myCLR;//添加命名空间域

class Program
{ 
    static void Main(string[] args)
    {
        //直接访问
        Person_CLI _cl = new Person_CLI();
        _cl.initPersonClass();
        _cl.setPersonInfo("Tom",10, 30.2);
        Console.ReadKey();
    }
}


正常输出结果
在这里插入图片描述

三、C++/CLI与COM组件对比

C++ ATL(Active Template Library)并不能像 C++/CLI 一样实现混合使用托管和非托管代码。C++ ATL 是一种基于 COM 技术的 C++ 库,主要用于编写 COM 组件和应用程序。它不是一种语言,而是一种库,提供了一些在编写 COM 组件时经常使用的类和函数。

假如已经有一个现有的 C++ 应用程序,并且想要让 C# 调用它,那么使用 C++ ATL 可能不是最好的选择,因为这需要将现有的 C++ 应用程序重写为 COM 组件,并在 C# 中使用 COM Interop 来访问该组件,这可能会带来一些复杂性和性能开销。

相比之下,使用 C++/CLI 则更加方便和直接。通过编写 C++/CLI 包装器,可以直接将现有的 C++ 应用程序集成到 .NET 应用程序中,并且可以充分利用 .NET 平台所提供的各种优势,如自动内存管理、强类型等。同时,C++/CLI 还支持混合使用托管和非托管代码,因此可以轻松地实现与操作系统 API、硬件驱动程序、第三方库等非托管系统的交互。

不过在一些情况下,使用 ATL 可能会比使用 C++/CLI 更加高效和灵活。这是因为 ATL 提供了许多内置的 COM 基础类和模板,使得开发者可以快速创建高效的 COM 组件。此外,ATL 还提供了一套可选的 Active Template Library 对象模型(ATL OLE DB),这个对象模型提供了对 OLE DB 数据库访问的支持,使得开发者可以更方便地实现数据库相关的功能。

基于COM组件的相关操作可以回顾:
基于COM组件实现C#调用C++类对象过程中的注意事项

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

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

相关文章

阿里P7晒出工资单:狠补了这个,真香...

据阿里HR部门发布的最新信息&#xff0c;2023年招聘岗位数将扩招3000&#xff0b;。但就2022年就业形势来看&#xff0c;大厂缩招裁员导致优质岗位竞争变得更加激烈&#xff0c;2023开年以来&#xff0c;也有不少大厂纷纷传来裁员的消息&#xff01;除了对面试者技术的要求变高…

Netty BIO/NIO/AIO介绍

概念介绍 1、 BIO(blocking I/O):同步阻塞IO,也即是传统的I/O。 2、 NIO (non-blocking IO): 也即是New I/O,使用它可以提供非阻塞式的高伸缩性网络。 3、AIO 即 NIO2.0, 叫做异步不阻塞的 IO。 AIO 引入异步通道的概念, 采用了 Proactor 模式, 简化了程序编写,有…

零拷贝(Zero-Copy)

一&#xff0c;数据的四次拷贝与四次上下文切换 很多应用程序在面临客户端请求时&#xff0c;可以等价为进行如下的系统调用&#xff1a; File.read(file, buf, len);Socket.send(socket, buf, len); 例如消息中间件 Kafka 就是这个应用场景&#xff0c;从磁盘中读取一批消息…

kafka介绍

1.kafka是什么 Kafka是一种高性能、可扩展、容错的分布式流处理平台&#xff0c;广泛应用于日志收集、实时数据处理、消息传递等场景所开发的一个消息队列中间件 2.kafka的优势 Kafka的优势在于其高吞吐量、可扩展性、容错性以及灵活的数据保留策略。它的高吞吐量是因为Kafk…

十一、Node.js

一、Node.js是什么&#xff1f; 在了解Node.js之前&#xff0c;我们先去了解一下什么叫v8引擎。这里参考一下其他博主的资料。 聊聊V8引擎_努力学习前端的77的博客-CSDN博客 这个时候我们再去看下Node.js的定义。 官方对Node.js的定义&#xff1a; Node.js是一个基于V8 Ja…

mysql优化-减少查询回表次数和回表数据量

减少数据回表常见的三种方式分别是1&#xff09;查询条件使用聚集索引&#xff1b;2&#xff09;使用索引下推&#xff1b;3&#xff09;使用索引覆盖。 1 查询条件使用聚集索引-避免回表查询 按照索引使用数据结构B树叶子结点是否包含表中全部字段&#xff0c;mysql 索引可以…

“数字中国·福启海丝”多屏互动光影艺术秀27日在福州举办

作为深化“数字海丝”的核心区、海上丝绸之路的枢纽城市&#xff0c;为喜迎第六届数字中国建设峰会盛大召开之际&#xff0c;福州市人民政府特此举办“数字中国福启海丝”多屏互动光影秀活动。本次光影秀活动是由福建省文化和旅游厅指导&#xff0c;福州市人民政府主办&#xf…

USB转串口芯片CH9101U

CH9101是一个USB总线的转接芯片&#xff0c;实现USB转异步串口。提供了常用的MODEM联络信号&#xff0c;用于为计算机扩展异步串口&#xff0c;或者将普通的串口设备或者MCU直接升级到USB总线。 特点 全速USB设备接口&#xff0c;兼容USB V2.0。内置固件&#xff0c;仿真标准串…

CH9121网络串口透传应用

概述 随着物联网技术的普及&#xff0c;越来越多的传统设备出现联网功能需求。串口作为使用较为广泛的一种通信接口&#xff0c;串口转以太网&#xff0c;进行远程数据传输需求逐渐显现出来。CH9121内部集成TCP/IP协议栈&#xff0c;无需编程&#xff0c;即可轻松实现网络数据…

撰写项目文档: 节省时间的技巧和模板

高质量的项目文档具有长期价值。它不仅有助于确保项目的成功&#xff0c;而且还可以作为未来项目和计划的参考&#xff01; 项目文档是任何项目的脉搏&#xff0c;它连接了成功运行项目所需的一切。 文档必须足够宽泛&#xff0c;以便开发能够取得进展。但要足够灵活&#xf…

DAB-Deformable-DETR源码学习记录之模型构建(二)

书接上回&#xff0c;上篇博客中我们学习到了Encoder模块&#xff0c;接下来我们来学习Decoder模块其代码是如何实现的。 其实Deformable-DETR最大的创新在于其提出了可变形注意力模型以及多尺度融合模块&#xff1a; 其主要表现在Backbone模块以及self-attention核cross-atten…

平台+AI:全面拥抱大模型的商业创新,打造企业数字化「柔性供应链」 | D3演讲实录

马斯克曾说&#xff1a;“高生产率解决诸多问题。” 在社会化内卷的大环境下&#xff0c;借助数智化“降本增效”已是不争事实。AI技术日新月异、大量信息繁杂涌现&#xff0c;无数原来烟囱式的模式亟需变革&#xff0c;平台与AI之间怎样融合&#xff0c;才能发挥更大的功效&a…

深度学习量化总结(PTQ、QAT)

背景 目前神经网络在许多前沿领域的应用取得了较大进展&#xff0c;但经常会带来很高的计算成本&#xff0c;对内存带宽和算力要求高。另外降低神经网络的功率和时延在现代网络集成到边缘设备时也极其关键&#xff0c;在这些场景中模型推理具有严格的功率和计算要求。神经网络…

如何减少项目在Corona和V-Ray中的3ds Max渲染时间?

相信在大多 3D 项目里&#xff0c;渲染是最耗费时间的部分&#xff0c;它不仅是建模和纹理化 3D 场景的过程&#xff0c;而是需要利用硬件来完成任务。我们在配备独立GPU和带有2到4个强大内核的CPU的中档计算机上&#xff0c;可以将3ds Max中创建和处理的项目轻松渲染完成&…

MATLAB实现车牌识别

车牌识别主要包括三个主要步骤&#xff1a;车牌区域定位、车牌字符分割、车牌字符识别。 本项目通过对拍摄的车牌图像进行灰度变换、边缘检测、腐蚀及平滑等过程来进行车牌图像预处理&#xff0c;并由此得到一种基于车牌颜色纹理特征的车牌定位方法&#xff0c;最终实现了车牌…

在Docker上部署SpringBoot项目

在Docker上部署SpringBoot项目 在学习中发现了部署的时候总是有各种问题,此文章只有操作步骤没有原理解释,只是用来提醒自己部署步骤 第一步:将SpringBoot项目打包成jar包 使用idea打包,点一下就行 第二部:编写Dockerfile文件 新建一个名为Dockerfile的文件,注意没有后缀…

improper Integral反常积分

笔记 笔记二 例题 hyperlink

安陆EGS20 SDRAM仿真

目录 一. 搭建仿真平台 二. 实现SDRAM连续写入1024个数据&#xff0c;然后再连续读出&#xff0c;并比较 1. 调试过程中问题&#xff1a; 2. 顶层代码 3. 功能代码 三. SDRAMFIFO实现上述功能调试 1. 代码设计要点 2. 仿真过程问题 3. 上板运行调试 安陆反馈&#xf…

80%的人都关注的电子合同签署疑问,君子签官方解答来了!

电子合同签错了在平台可以撤回吗&#xff1f;如果合同上名字签错了&#xff0c;有法律效力吗&#xff1f;签的电子合同&#xff0c;内容会不会被别人看见&#xff1f;… 最近&#xff0c;小编将80%的人都关注的电子合同签署问题进行了整理&#xff0c;官方专业解答帮助大家更好…

mac真机调试h5攻略

原因&#xff1a; h5项目想在mac本通过chrome://inspect/#devices调试 &#xff08;win上调试h5很简单&#xff0c;请参考&#xff1a;chrome真机调试Android_chrome 调试安卓_芒果终结者的博客-CSDN博客&#xff09; 调试步骤&#xff1a; 1. 需要下载安装安卓开发工具and…