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方法调用。代理负责委托对类接口的所有调用返回给托管对象,并公开其他不由类显式实现的接口,如IUnknownIDispatch

  • 向.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结构体会作为一个整体被复制到非托管堆栈上,然后传递给非托管函数。如果函数修改了结构体的内容,那么这些更改不会反映回原始的托管副本,除非我们将参数标记为refout,从而允许双向的数据流动。

总结:

封送类涉及到了解托管与非托管边界上的数据传输机制,包括但不限于上述提到的各种细节。正确地配置和管理这些细节可以帮助避免潜在的问题,确保应用程序之间的互操作性顺畅无误。

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

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

相关文章

大数据技术(六)—— Hbase集群安装

目录 一、Hbase安装 1、准备工作 1.1、安装rsync 1.2、编辑脚本 1.3、测试 2、安装Hadoop 3、安装zookeeper 3.1、下载最新稳定版 3.2、安装配置ZK 4、安装Hbase 4.1、解压文件 4.2、hbase-env.sh 4.3、backup-masters 4.4、配置hbase-site.xml 4.5、regionserv…

K8s集群平滑升级(Smooth Upgrade of K8S Cluster)

简介: Kubernetes ‌ (简称K8s)是一个开源的容器编排和管理平台,由Google开发并维护。它最初是为了解决谷歌内部大规模容器管理的问题而设计的,后来在2014年开源,成为云原生技术的核心组成部分。‌‌1 K8…

结合长短期记忆网络(LSTM)和无迹卡尔曼滤波器(UKF)的技术在机器人导航和状态估计中的应用前景

结合长短期记忆网络(LSTM)和无迹卡尔曼滤波器(UKF)的技术在机器人导航和状态估计中具有广泛的应用前景。如有滤波、导航方面的代码定制需求,可通过文末卡片联系作者获得帮助 文章目录 结合LSTM和UKF的背景结合LSTM和UKF的优势应用实例研究现状MATLAB代码示例结论结合LSTM和…

Spring源码下载与测试

引言 下载了Spring源码想阅读阅读,发现用的是Gradle,原来实习的时候公司用的也是Gradle,但不怎么会用,感觉相比于Maven,Gradle更适合非常大型的项目,因为他的jar包下载的是真快 下载 由于Spring6开始就强…

【HarmonyOS之旅】ArkTS语法(三) -> 渲染控制

目录 1 -> 条件渲染 2 -> 循环渲染 3 -> 数据懒加载 3.1 -> IDataSource类型说明 3.2 -> DataChangeListener类型说明 ArkTS也提供了渲染控制的能力。条件渲染可根据应用的不同状态,渲染对应状态下的UI内容。循环渲染可从数据源中迭代获取数据&…

再见2024,你好2025

再见2024,你好2025 1月2月3月4月5~10月11~12月一些收获读书跑步工作 为了让这篇博客不那么平淡,一句话可以总结为:平平无奇的琐碎,没有亮点成果。 也可以数字化概述:涨了1万粉,赚了10万,跑步300…

阴阳师の新手如何速刷5个SP/SSR?!(急速育成)

目标:攒5个SP/SSR式神,参与急速育成,省四个黑蛋(想要快速升级技能而且经常上场的式神在攒够5个式神前先不升级)【理论上组成:10蓝40蓝预约召唤福利20修行or抽卡】 关键点:蓝票,新手…

Kerberos用户认证-数据安全-简单了解-230403

hadoop安全模式官方文档:https://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-common/SecureMode.html kerberos是什么 kerberos是计算机网络认证协议,用来在非安全网络中,对个人通信以安全的手段进行身份认证。 概念&#…

第 29 章 - ES 源码篇 - 网络 IO 模型及其实现概述

前言 本文介绍了 ES 使用的网络模型,并介绍 transport,http 接收、响应请求的代码入口。 网络 IO 模型 Node 在初始化的时候,会创建网络模块。网络模块会加载 Netty4Plugin plugin。 而后由 Netty4Plugin 创建对应的 transports&#xff0…

SQL 基础教程 - SQL SELECT 语句

SQL SELECT DISTINCT 语句 SELECT DISTINCT 语句用于返回唯一不同的值。 在表中,一个列可能会包含多个重复值,有时您也许希望仅仅列出不同(distinct)的值。 DISTINCT 关键词用于返回唯一不同的值。 SQL SELECT DISTINCT 语法 …

计算机网络基础知识(7)中科大郑铨老师笔记

协议层次及服务模型 计算机网络的分层设计方法,将复杂的网络功能分解为多个层次,每一层实现特定的功能。 互联网中的TCP/IP协议族,包括物理层、链 路层、网络层、传输层和应用层的功能。然后,数据传输的 过程,从应用层…

Microsoft word@【标题样式】应用不生效(主要表现为在导航窗格不显示)

背景 随笔。Microsoft word 2013基础使用,仅做参考和积累。 问题 Microsoft word 2013,对段落标题文字应用【标题样式】不生效(主要表现为在导航窗格不显示)。 图1 图2 观察图1和图2,发现图1的文字在应用【标题一】样…

TP 钱包插件版本的使用

目前 TokenPocket 的几个平台中,以 ios 和 安卓版本最为常见,其实很少有人知道,浏览器上有一个插件版本的 Tp, 用电脑多的话,这也是一个挺好的选择。 最新版本现在支持Chrome、Brave 浏览器、Edge(Firefox及Opera正在…

微信流量主挑战:三天25用户!功能未完善?(新纪元4)

🎉【小程序上线第三天!突破25用户大关!】🎉 嘿,大家好!今天是我们小程序上线的第三天,我们的用户量已经突破了25个!昨天还是16个,今天一觉醒来竟然有25个!这涨…

【AndroidAPP】权限被拒绝:[android.permission.READ_EXTERNAL_STORAGE],USB设备访问权限系统报错

一、问题原因 1.安卓安全性变更 Android 12 的安全性变更,Google 引入了更严格的 PendingIntent 安全管理,强制要求开发者明确指定 PendingIntent 的可变性(Mutable)或不可变性(Immutable)。 但是&#xf…

打印进度条

文章目录 1.Python语言实现(1)黑白色(2)彩色:蓝色 2.C语言实现(1)黑白颜色(2)彩色版:红绿色 1.Python语言实现 (1)黑白色 import sys import timedef progress_bar(percentage, width50):"""打印进度条:param percentage: 当前进度百分比…

ubuntu 使用samba与windows共享文件[注意权限配置]

在Ubuntu上使用Samba服务与Windows系统共享文件,需要正确配置Samba服务以及相应的权限。以下是详细的步骤: 安装Samba 首先,确保你的Ubuntu系统上安装了Samba服务。 sudo apt update sudo apt install samba配置Samba 安装完成后&#xff0c…

数据结构(哈希表)

背景 在对数据的日常处理中,查找是一项基本操作。通常,查找算法都是基于对比的,比如在一条链表中有n个节点,要找到其中的某个节点,最基本的思路就是从头到尾依次遍历每个节点,依次对比每个节点是否是想要的…

【每日学点鸿蒙知识】模拟器开启网络、长时任务、兼容性测试支持、丢帧定位、SO中访问rawfile等

1、模拟器如何开启网络? 模拟器使用的是电脑本身的网络,不通过代理即可访问网络。 2、创建子window后,锁屏很短时间内,应用会被杀死? 没开长时任务,锁屏和退后台保活要开长时任务。 应用退至后台后&…

如何解决Eigen和CUDA版本不匹配引起的错误math_functions.hpp: No such file or directory

Apollo9针对RTX40的docker环境里的Eigen库版本是3.3.4,CUDA是11.8: 编译我们自己封装模型的某些component代码时没问题,编译一个封装occ模型的component代码时始终报错: In file included from /usr/include/eigen3/Eigen/Geometry:11:0, …