什么是对象编组?

Posted

技术标签:

【中文标题】什么是对象编组?【英文标题】:What is object marshalling? 【发布时间】:2010-09-14 07:52:31 【问题描述】:

我经常听到这个概念,但我不太了解它是什么。

【问题讨论】:

您确实应该为此添加更多内容,例如您正在寻找的上下文。例如,一个例子:.net 中的编组是将数据从托管类型转换为非托管类型以跨越边界的过程。它也可以在其他几种情况下使用。 @mattlant:编组在任何情况下都意味着同样的事情。这些只是不同的实现。 【参考方案1】:

将内存中的对象转换为可以写入磁盘或通过网络发送等的格式。

Wikipedia's description.

【讨论】:

显然这就是“序列化”的定义; “编组”略有不同:***.com/questions/770474/… @StephThirion 你的意思是一个对象,如果未序列化,只能有状态,不会有任何代码库,即它的任何函数都不能被调用,它只是一个结构化的数据类型。而且,如果对同一个对象进行编组,那么它将具有其代码库以及结构,并且可以调用其函数?【参考方案2】:

我不敢苟同,***对此很清楚。

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

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

【讨论】:

不过,定义可能会因上下文而略有不同。 @david:定义!= 实现。 这算不上“好斗”,而是在回答这个问题:“我查了谷歌,但没有明确的描述”。【参考方案3】:

人们已经很清楚地定义了编组,所以我将跳过定义并跳转到一个示例。

远程过程调用使用编组。调用远程函数时,您必须将参数编组为某种标准格式,以便可以通过网络传输。

【讨论】:

【参考方案4】:

Marshalling 是将对象的内存表示转换为可以存储或传输的数据格式的过程。它也称为serialization(尽管在某些情况下可能会有所不同)。对象的内存表示可以存储为二进制或 XML 或任何适合存储和/或传输的格式,以允许您解组它并取回原始对象。

作为一个使用示例,如果您有一些带有客户端和服务器组件的在线游戏,并且您希望将包含玩家统计数据和世界坐标的玩家对象从客户端发送到服务器(或相反),您可以简单地在客户端编组它,通过网络发送它,然后在另一端解组它,它会出现在服务器上,就好像对象是在服务器本身上创建的一样。这是一个红宝石示例:

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

【讨论】:

【参考方案5】:

我将谷歌搜索澄清为“数据编组”,第一次点击是on some place called webopedia,这非常好。要点是您将数据来回转换为一种形式,以便通过网络传输。它解决的问题是您不能真正通过网络以程序可用的形式传输数据。您必须解决许多问题,包括数据的字节顺序、如何存储复杂数据类型(如字符串)等。

编组不仅是为了解决网络传输问题,还包括其他问题,例如从一种架构到另一种架构,可能是不同的语言,尤其是那些可能使用虚拟机之类的语言,以及其他“翻译”问题。

【讨论】:

【参考方案6】:

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

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

【讨论】:

【参考方案7】:

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

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

【讨论】:

【参考方案8】:

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

例如,将结构编组到 XML 文档中以发送到 Web 服务,或编组指针以发送到不同的线程单元。

【讨论】:

【参考方案9】:

在编程的一般意义上,它只是意味着以一种格式获取数据并将其转换为其他子系统可以接受的格式。

【讨论】:

【参考方案10】:

编组是跨 ABI 边界调用时需要进行的调用参数转换。边界可能在COM客户端和COM服务器之间,其中COM客户端的ABI的类型需要通过COM库编组为COM二进制的ABI(在COM中,编组也可以指在同一进程内跨越单元边界时所需的参数到要发送到所属线程的消息队列以由 COM 窗口过程处理和解组的消息格式,并且在跨越进程边界的情况下,附加的由 COM 代理编组到 RPC/LPC 的步骤,即将 LPC 消息发送到 LPC 端口)。边界可能是在虚拟环境中执行高级代码与在/设置环境中实现环境的本机代码之间,其中在高级代码的 ABI 之间发生转换,在母语的 ABI,以及与这些类型相关的母语的典型 ABI。

第二种情况的一个例子是 Mono .NET。您可以从非托管(本机)代码(C++,不由虚拟机库管理,而是由虚拟机库管理和运行,由内部对象和结构表示)调用托管代码(高级语言)链接到库),并且您还可以在使用虚拟机库 API 设置虚拟机时基于 C++ 代码进行的内部绑定执行从 C# 到非托管(本机)代码 (C++) 的本机调用。例如,C# 中的System.String 在内部由MonoString 表示。 MonoString 是一个使用 C++ ABI 的 C++ 对象,但与标准使用方式以及本机代码期望字符串类型的参数在 ABI 中表示的方式不同,因为 VM 库已在逻辑上实现了它的使用 C++ ABI 的某种排列来拥有 ABI - 装在 MonoString* 类型的 C++ 对象中,而不是 const wchar_t*。使用 P/Invoke (which performs automatic marshalling) 将 System.String 传递给 C# 中的本机调用会导致在发生自动编组时将 const wchar_t* 传递给本机调用。但是,当您使用内部调用时,它将作为MonoString* 传递,C++ 函数将必须对其自身进行编组,然后编组返回到 VM 的逻辑 ABI 类型所需的任何内容。只有 blittable 类型在使用内部调用时不需要编组,例如 int,这是一个 System.Int32,作为 gint32 传递,这只是一个 int

另一个例子是Spidermonkey JS engine,它在 C++ 原生类型 htmlElement 和内部运行时表示 JSObject 之间编组,JSObject 表示 javascript 中的 HTMLElement 类型。

【讨论】:

以上是关于什么是对象编组?的主要内容,如果未能解决你的问题,请参考以下文章

如果它是一个 Rest 控制器,如何确保 Spring boot 自动编组一个类的对象

如何将 C++ 本机对象编组到托管 C++ CLI

带有 java.lang.Object 字段的 JAXB 编组对象

无法使用camel编组格式化LocalDate对象

使用 eclipselink 在 JPA 对象上进行 jaxb 编组期间的日期对话错误

JAXB:如何编组列表中的对象?