C#封送类
封送类(Marshaling classes)在.NET框架中扮演着至关重要的角色,尤其是在托管代码与非托管代码之间进行数据交换时。封送过程涉及到将托管环境中的对象转换为非托管环境中可以理解的形式,并且反之亦然。这一过程确保了两种不同类型的代码能够有效地通信和协作。
以下是封送类、结构和联合
| 类型 | 描述 | 示例 |
|---|---|---|
| 按值传递类 | 将具有整数成员的类传递为In/Out参数,与托管的情形相似。 | SysTime 示例 |
| 按值传递结构 | 将结构作为In参数传递。 | 结构示例 |
| 按引用传递结构 | 将结构作为In/Out参数传递。 | OSInfo 示例 |
| 具有内嵌结构(平展)的结构 | 传递非托管函数中表示内嵌结构的结构的类。此结构再托管的原型中将平展为一个的结构。 | FindFile 示例 |
| 具有指向另一结构的指针的结构 | 将包含指向第二结构的指针的结构作为成员传递。 | 结构示例 |
| 按值传递具有整数的结构数组 | 将仅包含整数的结构数组作为In/Out参数进行传递。可以更改数组的成员。 | 数组示例 |
| 按引用传递具有整数和字符串的结构数组 | 将包含整数和字符串的结构数组作为Out参数参数。被调用的函数为数组分配内存。 | OutArrayOfStructs 示例 |
| 具有值类型的联合 | 传递具有值类型(整数和双精度)的联合。 | 联合示例 |
| 具有混合类型的联合 | 传递具有混合类型(整数和字符串)的联合。 | 联合示例 |
| 具有特定平台的布局的结构 | 使用本机打包的传递类型。 | 平台示例 |
| 结构中的null值 | 传递空引用(Visual Basic中为Nothing),而不传递对值类型的引用。 | HandleRef 示例 |
类的封送
当涉及到类的封送时,需要注意的是,在.NET Framework中,类是引用类型,而结构体是值类型。这意味着类实例通过引用传递,而结构体则是通过复制整个结构体的内容来传递。对于类而言,默认情况下它们只能通过COM互操作来进行封送,并总是作为接口被封送。
对于类而言,默认情况下它们只能通过COM互操作来进行封送,并总是作为接口被封送。具体来说:
-
向COM传递类:当托管类传递给COM时,互操作封送处理程序会自动使用COM代理包装该类,并将由代理生成的类接口传递到COM方法调用。代理负责委托对类接口的所有调用返回给托管对象,并公开其他不由类显式实现的接口,如
IUnknown和IDispatch。 -
向.NET代码传递类:当接口传递回托管代码时,互操作封送处理程序负责用适当的包装器包装接口,并将这个包装器传递给托管方法。每个COM对象实例都有一个唯一的包装器,无论该对象实现了多少个接口。例如,如果一个COM对象实现了五个不同的接口,则只有一个包装器实例存在,它公开所有这五个接口。
封送类的默认行为
对于某些特定的.NET类型,如数组、布尔值、字符、委托、类、对象、字符串和结构等,默认的封送规则已经定义好了。这些规则决定了数据如何在托管和非托管内存之间传递。例如,.NET数组通常会被封送成指向数组元素本机表示形式的指针;而对于字符串,默认情况下会根据上下文选择合适的编码方式(如UTF-16, ANSI, UTF-8等),并且可以通过设置MarshalAs属性来指定更具体的封送选项。
自定义封送
尽管有默认的封送规则,但在很多实际应用场景下,开发者可能需要更加精细地控制封送过程。这时就可以利用MarshalAsAttribute属性来指定参数或字段应该怎样被封送。例如,如果你想要将字符串作为以null结尾的UTF-8字符串发送,你可以这样做:
[LibraryImport("somenativelibrary.dll")]
static extern int MethodA([MarshalAs(UnmanagedType.LPStr)] string parameter);
//或者
[LibraryImport("somenativelibrary.dll", StringMarshalling = StringMarshalling.Utf8)]
static extern int MethodB(string parameter);
示例:封送具有嵌套结构的类
假设我们有一个C++ DLL导出了一个名为MYPERSON3的结构体,其中包含了另一个结构体MYPERSON以及一个整数成员age。要在C#中正确地封送这样的结构体,我们可以定义相应的托管结构如下:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MyPerson
{public string first;public string last;
}[StructLayout(LayoutKind.Sequential)]
public struct MyPerson3
{public MyPerson person;public int age;
}
接着,我们需要为非托管函数创建一个托管原型,并确保正确地处理结构体的封送。如果我们知道函数接受的是按值传递的MYPERSON3结构体,那么我们的C#声明可能会像这样:
private static class NativeMethods
{[DllImport("..\\LIB\\PinvokeLib.dll")]public static extern void TestStructInStruct3(MyPerson3 person3);
}
在这个例子中,MyPerson3结构体会作为一个整体被复制到非托管堆栈上,然后传递给非托管函数。如果函数修改了结构体的内容,那么这些更改不会反映回原始的托管副本,除非我们将参数标记为ref或out,从而允许双向的数据流动。
总结:
封送类涉及到了解托管与非托管边界上的数据传输机制,包括但不限于上述提到的各种细节。正确地配置和管理这些细节可以帮助避免潜在的问题,确保应用程序之间的互操作性顺畅无误。
相关文章:
C#封送类
封送类(Marshaling classes)在.NET框架中扮演着至关重要的角色,尤其是在托管代码与非托管代码之间进行数据交换时。封送过程涉及到将托管环境中的对象转换为非托管环境中可以理解的形式,并且反之亦然。这一过程确保了两种不同类型…...
2024年度学习总结
2024年是我学业生涯的结束,是我职业生涯的开始。2024年6月19日我顺利研究生毕业,进入体制内,陆止于此,海始于斯,知识和文化最大的魅力,大概就是教会人谦卑和敬畏。读研的目的不是为了单纯拿到哪个证书&…...
我的博客年度之旅:感恩、成长与展望
目录 感恩有你 技能满点 新年新征程 嘿,各位技术大佬、数码潮咖还有屏幕前超爱学习的小伙伴们!当新年的钟声即将敲响,我们站在时光的交汇点上,回首过往,满心感慨;展望未来,豪情满怀。过去的这…...
undefined symbol: __nvJitLinkComplete_12_4, version libnvJitLink.so.12
目录 我的解决方法: 测试: 报错: undefined symbol: __nvJitLinkComplete_12_4, version libnvJitLink.so.12 from torch._C import * # noqa: F403 ImportError: /mnt/pfs/users/lbg/envs/mmpano/lib/python3.9/site-packages/torch/lib…...
【OTA】论文笔记--《智能网联汽车整车OTA功能设计研究》智能网联汽车OTA系统设计分析报告
智能网联汽车OTA系统设计分析报告 引言 随着汽车智能化、网联化水平不断提升,现代汽车中电子控制单元(ECU)的数量和复杂度持续增加。据统计,高级轿车上电子电气元件的成本已占整车开发成本的60%~70%。为了实现对这些电控单元的软件开发调试、数据标定、文件更新和故障修复,…...
c#String和StringBuilder
目录 一,String 1,string的特点: 2,string常用方法 (1)Length (2)Substring() (3)ToUpper() (4)ToLower() (5&…...
【Linux】HTTP协议
之前,我们已经做过了自定义协议,事实上,已经有很多现成已经做好又非常好用的协议,它们都是相同的,比如HTTP协议。所谓HTTP协议,就是超文本传输协议,定义了客户端和服务器之间是如何通信的&#…...
计算机网络 (14)数字传输系统
一、定义与原理 数字传输系统,顾名思义,是一种将连续变化的模拟信号转换为离散的数字信号,并通过适当的传输媒介进行传递的系统。在数字传输系统中,信息被编码成一系列的二进制数字,即0和1,这些数字序列能够…...
《向量数据库指南》——Milvus Cloud 2.5:Sparse-BM25引领全文检索新时代
Milvus Cloud BM25:重塑全文检索的未来 在最新的Milvus Cloud 2.5版本中,我们自豪地引入了“全新”的全文检索能力,这一创新不仅巩固了Milvus Cloud在向量数据库领域的领先地位,更为用户提供了前所未有的灵活性和效率。作为大禹智库的向量数据库高级研究员,以及《向量数据…...
Unity3D 网络框架设计详解
前言 Unity3D是一款强大的跨平台游戏开发引擎,网络框架的设计对于实现客户端与服务器之间的稳定通信至关重要。本文将详细介绍Unity3D网络框架的设计原理、技术要点以及代码实现。 对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一…...
网络渗透测试实验四:CTF实践
1.实验目的和要求 实验目的:通过对目标靶机的渗透过程,了解CTF竞赛模式,理解CTF涵盖的知识范围,如MISC、PPC、WEB等,通过实践,加强团队协作能力,掌握初步CTF实战能力及信息收集能力。熟悉网络扫描、探测HTTP web服务、目录枚举、提权、图像信息提取、密码破解等相关工具…...
Wend看源码-Java-Collections 工具集学习
摘要 java.util.Collections它提供了一系列静态方法,用于对集合(如List、Set、Map等)进行操作。这些操作包括排序、查找、替换、同步等多种功能,帮助开发者更方便地处理集合数据。以下是Collections 提供的一些主要方法的总结。…...
[JAVA]MyLogger
import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.logging.*;/*** 可以自已定义日志打印格式,这样看起来比较方便些**/ class MyFormatter extends Formatter {Overridepublic String format(LogRecord ar…...
玩转OCR | 腾讯云智能结构化OCR初次体验
目录 一、什么是OCR(需要了解) 二、产品概述与核心优势 产品概述 智能结构化能做什么 举例说明(选看) 1、物流单据识别 2、常见证件识别 3、票据单据识别 4、行业材料识别 三、产品特性 高精度 泛化性 易用性 四、…...
记一次 dockerfile 的循环依赖错误
文章目录 1. 写在最前面1.1 具体循环依赖的例子 2. 报错的位置2.1 代码快速分析2.2 代码总结2.3 关于 parser 的记录 3. 碎碎念 1. 写在最前面 笔者在使用 dockerfile 多阶段构建的功能时,写出了一个「circular dependency detected on stage: xx」的错误。 解决方…...
Trimble天宝X9三维扫描仪为建筑外墙检测提供了全新的解决方案【沪敖3D】
随着城市化进程的快速推进,城市高层建筑不断增多,对建筑质量的要求也在不断提高。建筑外墙检测,如平整度和垂直度检测,是衡量建筑质量的重要指标之一。传统人工检测方法不仅操作繁琐、效率低下,还难以全面反映墙体的真…...
【MySQL】深度学习数据库开发技术:使用CC++语言访问数据库
**前言:**本节内容介绍使用C/C访问数据库, 包括对数据库的增删查改操作。 主要是学习一些接口的调用, 废话不多说, 开始我们的学习吧! ps:本节内容比较容易, 友友们放心观看哦! 目录 准备mysql…...
LabVIEW化工实验室设备故障实时监测
化工实验室中,各类设备的运行状态直接影响实验的精度与安全性。特别是重要分析仪器的突发故障,可能导致实验中断或数据失效。为了实现设备运行状态的实时监控与故障快速响应,本文提出了一套基于LabVIEW的解决方案,通过多参数采集、…...
单例模式懒汉式、饿汉式(线程安全)
饿汉式单线程安全吗 饿汉式单例(Eager Singleton)是线程安全的。这种实现方式在类加载时就创建了单例实例,因此在多线程环境中,不存在多个线程同时创建实例的问题。 饿汉式单例的实现 以下是一个饿汉式单例的示例: …...
Cursor登录按钮点击没反应
问题 系统:Windows11 Cursor:Cursor 0.44.9 当安装Cursor打开进行登录时,点击Sign in没反应 解决方案 1.打开window11的设置 2.点击应用中的默认应用 3.在设置应用程序的默认值中搜索Google(没有Google浏览器的尝试下载一个&a…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
