什么是对象编组?

69

我经常听到这个概念,但并没有很好地掌握它。


2
@mattlant:在每个实例中,"Marshalling" 的意思都是相同的。那些只是不同的实现方式。 - GEOCHET
10个回答

46

将存储在内存中的对象转换为可写入磁盘、发送到网络等格式。

维基百科的描述


29
显然,这就是“序列化”的定义;而“编组”略有不同:https://dev59.com/p3RA5IYBdhLWcg3w8iol - Steph Thirion
@StephThirion 你的意思是,如果一个对象被反序列化,它只能有状态,没有代码库,也就是说它的任何函数都不能被调用,它只是一种结构化数据类型。而且,如果同一个对象被编组,那么它将具有其代码库以及结构,可以调用其函数? - bjan

37

我持不同意见,维基百科对此非常清楚。

在计算机科学中,编组(类似于序列化)是将对象的内存表示转换为适合存储或传输的数据格式的过程。通常在数据必须在计算机程序的不同部分之间移动或从一个程序移动到另一个程序时使用。

http://en.wikipedia.org/wiki/Marshalling_(computer_science)


定义可能会根据上下文略有不同。 - dnclem
2
@david:定义不等于实现。 - GEOCHET
这并不是什么“好斗”的言论,而是回应了这个问题:“我查了谷歌,但没有找到清晰的描述”。 - GEOCHET

16

人们已经很清楚地定义了“marshalling”,所以我将跳过定义并举一个例子。

远程过程调用使用了marshalling。当调用远程函数时,您需要将参数转换为某种标准格式,以便能够在网络上传输。


9

编组是将对象的内存表示转换为可存储或传输的数据格式的过程。它也被称为序列化(尽管在某些情况下可能不同)。对象的内存表示可以存储为二进制或XML或适合存储和/或传输的任何格式,以使您可以对其进行解组并获取原始对象。

作为使用示例,如果您有一个带有客户端和服务器组件的在线游戏,并且您想要从客户端向服务器(或反之)发送包含玩家统计信息和世界坐标的玩家对象,则可以简单地在客户端进行编组,通过网络发送它,然后在另一端进行解组,对于服务器来说,它就像对象是在服务器本身上创建的一样。以下是一个Ruby示例:

srcplayer = Player.new
# marshal (store it as string)
str = Marshal.dump(srcplayer)
#unmarshal (get it back)
destplayer = Marshal.load(str)

4
我把谷歌搜索词条精确地定位在“数据编排”,第一个链接是 webopedia,这个网站解释得很好。其核心意思是把数据转换成适合在网络上传输的形式。它解决的问题是:无法直接以程序可用的形式在网络上传输数据。你需要解决多个问题,包括数据的字节序、如何存储复杂数据类型(如字符串)等。
编排不仅仅解决网络传输问题,还可以解决其他问题,比如从一种体系结构转换到另一种体系结构,可能涉及不同的语言,特别是那些可能使用虚拟机等东西的语言,以及其他“翻译”问题。

4

Marshalling是在应用程序边界或不同数据格式之间转移数据的过程。Marshalling非常常见,例如将数据写入磁盘或数据库就是技术上的marshalling,但该术语往往用于描述针对“外部”API或进程间通信的数据转换。

例如,在.NET中,管理和非托管代码之间的通信(例如访问某些win32 API)可能需要marshalling,以便在托管C#对象和C/C++样式对象(结构体、句柄、输出缓冲区等)之间进行转换。静态Marshal类的帮助可能会有所帮助。


3

它意味着将任何数据转换为另一种数据类型以传输到另一个系统。

例如,将结构体编组成XML文档发送到Web服务,或者编组指针发送到不同的线程公寓。


2
基本上,它是一个用于将对象(或类似物)通用转换为另一种表示形式的表达式,例如可以发送到网络或存储到磁盘中(通常是字符串或二进制流)。相反的是解组(unmarshalling),描述了读取编组表示并重新创建先前存在的对象或内存结构的方向。

另一个当前日常示例是JSON。


1

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。
另一个例子是Spidermonkey JS engine,它在C++本地类型HTMLElement和内部运行时表示JSObject之间进行编组,后者表示javascript中的HTMLElement类型。

1
在编程中,通俗地说,它指的是将数据从一种格式转换为另一些其他子系统可以接受的格式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接