关于Marshal 类的整理
在两个不同的实体(两个线程或者进程甚至机器、在Managed和Unmanaged之间)进行方法调用和参数传递的时候,具体的调用方法和参数的内存格式可能需要一定的转换,这个转换的过程叫做Marshal。
Marshal就是把一个结构(类)序列化成一段内存,然后送到另一个进程(.net中Application domain)中供另一个进程中的函数使用。
比如你的一个结构
struct{
Pen pen;
}s; s是一个指向已有的Pen对象的引用,当你把s传给本进程中的一个函数f时,f可以很容易地找到pen的实际对象,但如果你把s传到另外一个进程时,甚至是另外一台机器上的进程时,这个进程就没办法找到pen的实际内容。Marshal技术则可以把pen对象中的所有实际内容按规则放到一个缓冲中,(所有的引用或指针都要转换成实际对象)然后把缓冲中的内容送到另一个进程,函数调用完成再用同样方式把结果返回来。
在RPC,Interop,COM中Marshal应用很多。
| 类别 | 成员 |
|---|---|
| 高级封送处理 |
GetManagedThunkForUnmanagedMethodPtr、GetUnmanagedThunkForManagedMethodPtr、NumParamBytes |
| COM 库函数 |
BindToMoniker、GetActiveObject |
| COM 实用工具 |
ChangeWrapperHandleStrength、CreateWrapperOfType、GetComObjectData、GetComSlotForMethodInfo、GetEndComSlot、 GetMethodInfoForComSlot、GetStartComSlot、ReleaseComObject、SetComObjectData |
| 数据转换 |
托管到非托管:Copy、GetComInterfaceForObject、GetIDispatchForObject、GetIUnknownForObject、StringToBSTR、StringToCoTaskMemAnsi、 StringToCoTaskMemAuto、StringToCoTaskMemUni、StringToHGlobalAnsi、StringToHGlobalAuto、StringToHGlobalUni、StructureToPtr、 UnsafeAddrOfPinnedArrayElement 非托管到托管:Copy、GetObjectForIUnknown、GetObjectForNativeVariant、GetObjectsForNativeVariants、GetTypedObjectForIUnknown、 GetTypeForITypeInfo、PtrToStringAnsi、PtrToStringAuto、PtrToStringBSTR、PtrToStringUni 属性:SystemDefaultCharSize、SystemMaxDBCSCharSize |
| 直接读取和写入 | ReadByte、ReadInt16、ReadInt32、ReadInt64、ReadIntPtr、WriteByte、WriteInt16、WriteInt32、WriteInt64、WriteIntPtr |
| 错误处理 | COM:GetHRForException、ThrowExceptionForHR
Win32:GetLastWin32Error、GetExceptionCode、GetExceptionPointers 两者:GetHRForLastWin32Error |
| 承载实用工具 | GetThreadFromFiberCookie |
| IUnknown | AddRef、QueryInterface、Release |
| 内存管理 | COM:AllocCoTaskMem、ReAllocCoTaskMem、FreeCoTaskMem、FreeBSTR
Win32:AllocHGlobal、ReAllocHGlobal、FreeHGlobal 两者:DestroyStructure |
| 平台调用实用工具 | Prelink、PrelinkAll、GetHINSTANCE |
| 结构检查 | OffsetOf、SizeOf |
| 类型信息 |
GenerateGuidForType、GenerateProgIdForType、GetTypeInfoName、GetTypeLibGuid、GetTypeLibGuidForAssembly、GetTypeLibLcid、 GetTypeLibName、IsComObject、IsTypeVisibleFromCom |
特别注意:Marshal.PtrToStringAuto方法:分配托管 String,并从非托管内存中存储的字符串向其复制第一个空字符之前的所有字符。
例1、
public struct ImageDataMsg
{
public char DataType;
public int Srv_index;
public char ConvertType;
//这个个地方要指定长度,这样就可以得到结构体的正确长度了
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public int[] VecLayer;//需要那几个图层。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public int[] GridLayer;//需要那几个栅格图层
public int Scale_index;//需要的是那个比例尺的图像
public int x_pos;
public int y_pos;
public int ClientArea_x;
public int ClientArea_y;
}
//使用这个方法将你的结构体转化为bytes数组
public static byte[] Struct2Bytes(ImageDataMsg obj)
{
int size = Marshal.SizeOf(obj);
byte[] bytes = new byte[size];
try
{
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(obj, ptr, false);
Marshal.Copy(ptr, bytes, 0, size);
Marshal.FreeHGlobal(ptr);
return bytes;
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
return bytes;
}
}
//使用这个方法将byte数组转化为结构体
public static object BytesToStuct2(byte[] bytes, ImageDataMsg type)
{
//得到结构体的大小
int size = Marshal.SizeOf(type);
//byte数组长度小于结构体的大小
if (size > bytes.Length)
{
//返回空
return null;
}
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将byte数组拷到分配好的内存空间
Marshal.Copy(bytes, 0, structPtr, size);
//将内存空间转换为目标结构体
object obj = Marshal.PtrToStructure(structPtr, typeof(ImageDataMsg));
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回结构体
return obj;
}
关于Marshal 类的整理的更多相关文章
- 利用C#Marshal类实现托管和非托管的相互转换
Marshal 类 命名空间:System.Runtime.InteropServices 提供了一个方法集,这些方法用于分配非托管内存.复制非托管内存块.将托管类型转换为非托管类型,此外还提供了在与 ...
- Marshal 类的内存操作的一般功能
Marshal类 提供了一个方法集,这些方法用于分配非托管内存.复制非托管内存块.将托管类型转换为非托管类型,此外还提供了在与非托管代码交互时使用的其他杂项方法. 命名空间:System.Runtim ...
- 客户端服务器通讯常用的一种方法——Marshal类
这个类是.NETFramework2.0中的类,所以我们能够将其用于Unity中.与这个类类似的还有litjson等,可能是为了节省字节空间,Marshal类只仅仅将值进行打包成bytes流,而jso ...
- 建筑设计类软件整理ACDSee,PS,CAD,Ecotect,SketchUp,Phoenics,Revit,Rhino,
关于建筑设计类软件整理 1 建筑设计类专业最常用软件如下,包括SU,CAD, REVIT,PS等. 2 sketch up 简称SU,中文名草图大师,在推敲方案,拉推体块时有着不可或缺的作用,而且随着 ...
- 【C#线程】 Marshal类基本概念
marshal:直译为"编排", 在计算机中特 指将数据按某种描述格式编排出来,通常来说一般是从非文本格式到文本格式的数据转化.unmarshal是指marshal的逆过程.比如在 ...
- C#通用类Helper整理
★前言 最近下载了tita_chou在CSDN上传的一个资源,是在工作中整理的C#帮助类,里面包含了很多实用的类,想到我之前收集过自己用到少的可怜的类,心生敬意啊.当粗略的查看了那个资源,发现 ...
- IOS开发--常用工具类收集整理(Objective-C)(持续更新)
前言:整理和收集了IOS项目开发常用的工具类,最后也给出了源码下载链接. 这些可复用的工具,一定会给你实际项目开发工作锦上添花,会给你带来大大的工作效率. 重复造轮子的事情,除却自我多练习编码之外,就 ...
- 反射(学习整理)----Class类和加载器ClassLoader类的整理
1.学习反射的时整理的笔记!Class类和ClassLoader类的简单介绍 反射机制中的Class Class内部到底有什么呢?看下图! 代码: Class cls=Person.class; .C ...
- Java集合常用类特点整理
集合的结构如下图所示: 集合的两个顶级接口分别为:Collection和Map Collection下有两个比较常用的接口分别是List(列表)和Set(集),其中List可以存储重复元素,元素是有序 ...
随机推荐
- 面渣逆袭:HashMap追魂二十三问
大家好,我是老三. HashMap作为我们熟悉的一种集合,可以说是面试必考题.简单的使用,再到原理.数据结构,还可以延伸到并发,可以说,就一个HashMap,能聊半个小时. 1.能说一下HashMap ...
- PHP 获取两个日期相差多少年,多少月,多少天,多少小时,并填充数组
PHP 获取两个日期相差多少年,多少月,多少天,多少小时,并填充数组 <?php /** * 获取两个日期相差多少年,多少月,多少天,多少小时,并填充数组 * @param [type] $st ...
- Linux命令行好玩的命令
0.cal 2019 #输出日历并显示今天是哪一天 1.命令"date",显示系统的当前日期和时间: 2.命令"date 040100002016",屏幕显示 ...
- 框架学习-MyBatis(01)
1.MyBatis是持久层框架 什么是持久化: 狭义:把数据永久性的保存到数据当中 广义:针对于数据库的所有操作都称为持久化操作,CreateReadUpdateDelete操作 2.有哪些持久层框架 ...
- Linux驱动实践:如何编写【 GPIO 】设备的驱动程序?
作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...
- 日常Java 2021/11/3
java网络编程 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来.java.net包中J2SE的APl包含有类和接口,它们提供低层次的通信细节.你可以直接使用这些类和接口, ...
- 带你全面了解 OAuth2.0
最开始接触 OAuth2.0 的时候,经常将它和 SSO单点登录搞混.后来因为工作需要,在项目中实现了一套SSO,通过对SSO的逐渐了解,也把它和OAuth2.0区分开了.所以当时自己也整理了一篇文章 ...
- Flume对接Kafka
目录 一.简单实现 1)flume的配置文件 二.自定义interceptor(使用kafka sink) 1)自定义 flume 拦截器 2)编写 flume 的配置文件 3)创建topic 4)启 ...
- Linux磁盘分区(二)之挂载卸载常用命令
Linux磁盘分区(二)之挂载卸载常用命令 转自:https://blog.csdn.net/qq_36183935/article/details/81053383 https: ...
- [转]C++中const的使用
原文链接:http://www.cnblogs.com/xudong-bupt/p/3509567.html 平时在写C++代码的时候不怎么注重const的使用,长久以来就把const的用法忘记了 写 ...