C++CLI——5委托、事件、反射和混合非托管代码

C++CLI——5委托、事件、反射和混合非托管代码

委托

C++中是有函数指针的,例如:long (*pf)(int,int),声明了一个函数指针,要求获取两个int并返回一个long的任意函数。在C#中是有委托概念的,其实原理就是将函数的执行委托给一个中间对象,和C++中的函数指针功能类似,但更强大(例如多播委托)。其使用与C#中使用委托基本相同。

//定义委托
delegate double NumbericOP(double);ref class OPs
{
public:static double Square(double d){return d * d;}double Circle(double r){return Math::PI * r * r;}
};
int main(array<System::String^>^ args)
{//委托赋予静态方法NumbericOP^ op = gcnew NumbericOP(&OPs::Square);double area = op->Invoke(3);double area1 = op(5);//委托赋予非静态方法OPs^ ops = gcnew OPs();NumbericOP^ op1 = gcnew NumbericOP(ops,&OPs::Circle);double area2 = op1(3);//多播委托NumbericOP^ op2;op2 += op1;op2 += op;double area3= op2(2);
}

事件

事件是基于委托的,只不过事件的触发必须在定义事件的类中,在外面只能调用+=和-=进行操作。其使用和C#中基本相同。

delegate void MyEventHandler(String^);ref class EvtSrc
{
public:event  MyEventHandler^ OnMyEvent;void Raise(String^ msg){OnMyEvent(msg);}
};ref class EvtRcv
{
public:EvtRcv(EvtSrc^ s){if (s == nullptr){throw gcnew ArgumentNullException("句柄无效");}src = s;src->OnMyEvent += gcnew MyEventHandler(this,&EvtRcv::EventMethod);}void EventMethod(String^ msg){Console::WriteLine(msg);}
private:EvtSrc^ src;};int main(array<System::String^>^ args)
{EvtSrc^ src = gcnew EvtSrc();EvtRcv^ rcv = gcnew EvtRcv(src);src->Raise("调用啦");Console::WriteLine("程序结束");
}

image-20240104162807268

反射

在C#中,反射是经常使用的功能之一,在C++/CLI中也支持反射,使用方法和C#使用反射的方法基本一致。

混合非托管代码

使用C++/CLI一般都是作为非托管代码和托管代码的中介,所以混合非托管代码在实际开发中经常用到。

混合类

ref class ManagedClass
{UnManagedClas* puc;//使用*而不是^说明这是非托管代码
}

不能直接这样做

ref class ManagedClass
{UnManagedClas puc;//错误
}

并且,不能在非托管代码中直接使用托管代码,因为在标准C++中无法识别^,也没有gc

class UnManagedClass
{ManagedClas^ puc;//错误
}

GCHandle类型

GCHandle类型可以实现托管类型作为非托管类型的一部分使用。使用静态GCHandle::Alloc方法创建句柄,使用句柄的Free方法释放它。将托管对象的指针传给非托管代码的步骤如下:

  1. 创建一个GCHandle对象来引用你的对象,GCHandle可以和整数互换。
  2. 将GCHandle传给非托管代码
  3. 非托管对象在不需你的对象时,调用Free释放对象

官方提供了gcroot辅助模板类,以避免亲自和Alloc和free打交道。

#include "gcroot.h"
using namespace System;
using namespace System::Runtime::InteropServices;ref class MyClass
{
public:int val;MyClass(int n) :val(n) {}};class UClass
{
public://mc是一个gcroot变量,里面包装了引用MyClass句柄的GCHandle,gcroot对象创建时自动创建GCHandle,销毁时自动释放GCHandlegcroot<MyClass^> mc;UClass(gcroot<MyClass^>pmc) :mc(pmc) {}int getValue(){return mc->val;}
};int main(array<System::String^>^ args)
{MyClass^ pm = gcnew MyClass(3);UClass uc(pm); //一旦uc离开作用域,则gcroot会被销毁,释放GCHandle,进而释放托管对象int v= uc.getValue();Console::WriteLine(v);Console::WriteLine("程序结束");
}

固定

因为有了gc的存在,非托管对象引用托管对象会出现错误,因为托管对象会发生移动,对象内部的成员也会跟着移动。如果要将托管对象的指针传给非托管参数,则需要将托管对象的指针进行固定。可根据需要固定部分或者整个托管对象的指针,但是如果固定了成员指针则整个对象也会被固定。

//非托管函数
void someFun(int* o)
{int n = *o;
}
int main(array<System::String^>^ args)
{array<int>^ arr1 = gcnew array<int>(3);//创建固定指针pin_ptr<int> pin = &arr1[0];someFun(pin);//固定指针能隐式转为int*pin = nullptr;//释放对象,让指针可以自由移动Console::WriteLine("程序结束");
}

拆装箱

和C#一样,装箱就是将值类型转成引用类型,拆箱就是将引用类型转为值类型。

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

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

相关文章

上海中考数学练一练:选择题专项练习和答案解析(1)

前不久&#xff0c;上海市教委发布了关于做好2024年上海市高中阶段学校招生&#xff08;以下简称“中招”&#xff09;报名工作的通知&#xff0c;初三的学子们目前已经进入到报名材料核对的环节了&#xff0c;也意味着2024年的中考倒计时6个月已经开始了。 那么&#xff0c;在…

安卓拍照扫描APP解决方案——基于深度学习的文本方向检测与校正

简介 在OCR&#xff08;光学字符识别&#xff09;系统中&#xff0c;为了提高OCR系统的性能&#xff0c;确保准确识别文本内容。图像预处理是一个关键的组成部分。其中&#xff0c;一个重要的任务是矫正文本方向。例如&#xff0c;在进行文字识别时&#xff0c;不仅需要有效地…

Js的String的replace(和replaceAll(

EcmaJavascriptJs的String的 replace( 和 replaceAll( 方法 String.prototype.replaceString.prototype.replaceAll 相同点 都是String.prototype的函数都是用于字符串替换都是两个参数第一个参数都可以是正则或字符串第二参数都可以是字符串或者回调函数, 回调会传入一个参…

32、[ShallowFBCSPNet、EEG-ITNet、EEGResNet、EEGInception]4种模型处理脑机接口-MOABB数据库+代码+结果

脑机接口基准之母—MOABB数据库介绍&#xff1a; 18、MOABB&#xff1a;BCI创新模型基准测试的群虫之心-CSDN博客 Dataset&#xff1a; BNCI 2014-001 Motor Imagery dataset. (BCI IV2a)&#xff1a; https://paperswithcode.com/dataset/bci-competition-4-version-iia …

AI小蜜批量写作助手:多级指令,插件,GPTs满足不同写作需求

为什么会开发这个脚本&#xff1f; 爆文项目的核心是矩阵怼量 具体怎么做这里介绍很清楚了&#xff1a; AI爆文撸流量主保姆级教程3.0脚本写作教程&#xff08;解放双手&#xff09; 我在刚做爆文项目时候&#xff0c;都是手动操作&#xff0c;复制指令&#xff0c;组合指令…

2023 | 美团技术团队热门技术文章汇总

新年好&#xff01;时光飞逝&#xff0c;我们告别了难忘的2023&#xff0c;迎来了充满希望的2024。再次感谢大家的一路相伴~~ 今天&#xff0c;我们整理了2023年公众号阅读量靠前的10篇技术文章&#xff0c;欢迎大家品阅。祝愿大家在新的一年里&#xff0c;幸福平安&#xff0…

[足式机器人]Part2 Dr. CAN学习笔记-动态系统建模与分析 Ch02-6频率响应与滤波器

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-动态系统建模与分析 Ch02-6频率响应与滤波器 1st order system 一阶系统 低通滤波器——Loss Pass Filter

C#上位机与欧姆龙PLC的通信10----开发专用的通讯工具软件(WPF版)

1、介绍 上节开发了一个winform版的通讯测试工具&#xff0c;这节再搞个wpf版的&#xff0c;wpf是什么&#xff1f;请自行百度&#xff0c;也可以看前面的博客&#xff0c;WPF真入门教程&#xff0c;wpf的界面效果是比winform漂亮&#xff0c;因为wpf使用了web项目中的css样式…

国图公考:2024年上半年中小学教师资格考试(笔试)报考须知

(一)信息填报时间&#xff1a;2024年1月12日9:00至1月15日16&#xff1a;00 (二)信息确认时间&#xff1a;2024年1月13日9:00至1月16日16&#xff1a;00 (三)网上缴费时间&#xff1a;2024年1月13日9:00至1月17日24&#xff1a;00

新年福利|这款价值数万的报表工具永久免费了

随着数据资产的价值逐渐凸显&#xff0c;越来越多的企业会希望采用报表工具来处理数据分析&#xff0c;了解业务经营状况&#xff0c;从而辅助经营决策。不过&#xff0c;企业在选型报表工具的时候经常会遇到以下几个问题&#xff1a; 各个报表工具有很多功能和特性&#xff0c…

硬盘基本知识(磁头、磁道、扇区、柱面)

概述 盘片&#xff08;platter&#xff09; 磁头&#xff08;head&#xff09; 磁道&#xff08;track&#xff09; 扇区&#xff08;sector&#xff09; 柱面&#xff08;cylinder&#xff09; 盘片 片面 和 磁头 硬盘中一般会有多个盘片组成&#xff0c;每个盘片包含两个面…

大数据毕设分享 flink大数据淘宝用户行为数据实时分析与可视化

文章目录 0 前言1、环境准备1.1 flink 下载相关 jar 包1.2 生成 kafka 数据1.3 开发前的三个小 tip 2、flink-sql 客户端编写运行 sql2.1 创建 kafka 数据源表2.2 指标统计&#xff1a;每小时成交量2.2.1 创建 es 结果表&#xff0c; 存放每小时的成交量2.2.2 执行 sql &#x…