我经常听到这个概念,但并没有很好地掌握它。
我经常听到这个概念,但并没有很好地掌握它。
将存储在内存中的对象转换为可写入磁盘、发送到网络等格式。
我持不同意见,维基百科对此非常清楚。
在计算机科学中,编组(类似于序列化)是将对象的内存表示转换为适合存储或传输的数据格式的过程。通常在数据必须在计算机程序的不同部分之间移动或从一个程序移动到另一个程序时使用。
人们已经很清楚地定义了“marshalling”,所以我将跳过定义并举一个例子。
远程过程调用使用了marshalling。当调用远程函数时,您需要将参数转换为某种标准格式,以便能够在网络上传输。
编组是将对象的内存表示转换为可存储或传输的数据格式的过程。它也被称为序列化(尽管在某些情况下可能不同)。对象的内存表示可以存储为二进制或XML或适合存储和/或传输的任何格式,以使您可以对其进行解组并获取原始对象。
作为使用示例,如果您有一个带有客户端和服务器组件的在线游戏,并且您想要从客户端向服务器(或反之)发送包含玩家统计信息和世界坐标的玩家对象,则可以简单地在客户端进行编组,通过网络发送它,然后在另一端进行解组,对于服务器来说,它就像对象是在服务器本身上创建的一样。以下是一个Ruby示例:
srcplayer = Player.new
# marshal (store it as string)
str = Marshal.dump(srcplayer)
#unmarshal (get it back)
destplayer = Marshal.load(str)
Marshalling是在应用程序边界或不同数据格式之间转移数据的过程。Marshalling非常常见,例如将数据写入磁盘或数据库就是技术上的marshalling,但该术语往往用于描述针对“外部”API或进程间通信的数据转换。
例如,在.NET中,管理和非托管代码之间的通信(例如访问某些win32 API)可能需要marshalling,以便在托管C#对象和C/C++样式对象(结构体、句柄、输出缓冲区等)之间进行转换。静态Marshal类的帮助可能会有所帮助。
它意味着将任何数据转换为另一种数据类型以传输到另一个系统。
例如,将结构体编组成XML文档发送到Web服务,或者编组指针发送到不同的线程公寓。
另一个当前日常示例是JSON。
Marshalling是调用跨ABI边界时需要进行的调用参数转换。该边界可能是COM客户端和COM服务器之间,其中COM客户端的ABI类型需要由COM库编组为COM二进制文件的ABI类型(在COM中,编组也可以指在同一进程内穿越公寓边界时所需的参数转换为要发送到所属线程的消息队列的格式,然后由COM窗口过程处理并解组,而在穿越进程边界的情况下,则需要通过COM代理将其编组到RPC/LPC,即LPC消息到LPC端口)。该边界可能是在虚拟环境中执行高级代码和实现环境/设置环境的本机代码之间,在这种情况下,高级代码的ABI与本地语言的典型ABI之间进行转换。
第二种情况的一个例子是Mono .NET。您可以从非托管代码(C ++,它不受虚拟机库管理,而是链接到该库)调用托管代码(高级语言,由虚拟机库管理和运行,并由内部对象和结构表示),您还可以基于C ++代码设置虚拟机时使用虚拟机库API进行内部绑定,从C#对非托管(本机)代码(C ++)执行本机调用。例如,C#中的System.String在内部由MonoString表示。MonoString是一个使用C ++ ABI的C ++对象,但使用方式与标准方式以及本机代码期望表示字符串类型参数在ABI中的方式不同,因为VM库已经逻辑上实现了自己的ABI,使用C ++对象类型MonoString *封装,而不是const wchar_t *。使用P / Invoke({{link1:执行自动编组}})在C#中将System.String传递给本机调用会导致将const wchar_t *作为自动编组传递给本机调用。然而,当使用内部调用时,它将作为MonoString *传递,C ++函数将不得不自己进行编组,然后将其需要返回的内容编组回VM的逻辑ABI类型。只有可平坦化类型在使用内部调用时不需要进行编组,例如{{link2:int
}},它是一个System.Int32,作为gint32传递,只是一个int。HTMLElement
和内部运行时表示JSObject
之间进行编组,后者表示javascript中的HTMLElement
类型。