什么是编组?当某物被“编组”时会发生什么?

84

我知道这个问题已经被问过了,至少 这里 有讨论。

但是对我来说没有一个令人满意的答案。关于与非托管代码互操作时的marshalling,有很多讨论,但从一个线程到另一个线程的marshalling呢?这在.NET中有时是必须的。

这使我想问,什么是marshalling?当你给出marshalling的定义时,如何定义它以解释互操作性的情况,以及在“marshalling”线程之间的情况?


3
你只是在获取已经存在于该线程中的更多内容。这是不可避免的,它是一个非常通用的术语。这并不意味着比“改变运行环境”更多的东西。 - Hans Passant
6个回答

100

在计算过程中,数据经常需要从一个站点移动到另一个站点,并且没有任何共享的内存。因此,一个计算发送包含数据的消息给另一个计算。

如果这些数据非常复杂,应该如何在消息中发送?

编组是将数据字段或整个相关结构转换为序列化字符串的过程,以便可以在消息中发送。要编组二进制数,可以将其转换为十六进制数字字符串,如果消息格式必须为文本,则采用此方法。如果消息将携带二进制数据,则可以将二进制数转换为4个小端规范化的二进制字节,并以这种方式发送。指针更难处理,通常必须将它们转换为抽象引用(例如,“节点编号”),这些引用与实际的内存位置无关。

当然,如果对数据进行编组,则最终必须进行“解组”,即读取序列流并重建传输的数据(结构)的过程。

通常,在库中有(解)编组例程用于完成此目的,有时甚至有工具可以生成所有所需的(解)编组例程调用来发送/接收数据。


19
Copsey是正确的:通常,编组用于描述将数据结构表示从一种计算机语言转换成通用表示形式,以便传递给另一种计算机语言中的另一个计算。即使在同一进程内跨语言调用也可能需要编组来移动数据。我向Reed的回答捐赠了一个点以表达我的认同。 - Ira Baxter
所以,marshal的意思和serialize一样吗? - Героям слава

38

“Marshalling”是将某种形式的数据翻译成另一种形式的过程。它是一个非常通用的术语,在许多地方使用,但其含义略有不同。

例如,在.NET中,当您使用本机类型时,交互层会将数据从.NET类型“marshals”到适当的形式以调用本机方法,然后再“marshals”结果回来。

至于在线程之间“marshalling”,通常情况下,您需要在与当前线程不同的线程上运行代码。例如,如果您正在使用Windows Forms,您无法在线程池线程上更改UI元素,因此您需要将调用“marshal”回UI线程。通过创建委托并通过Control.Invoke将委托传回用户界面线程(该方法使用相当复杂的系统将其发送回适当的同步上下文),然后在用户界面线程上运行委托。


14

维基百科 的定义其实相当不错。

对于内存序列化的概念,它与 marshalling 的概念是一致的:将从内存中表示(在某种程度上,就像没有任何表示一样——当某些东西在内存中时,它只是“存在”)转移到“硬拷贝”表示,无论是 XML 或者二进制流等。但是,根据您正在处理的内容,它也可能意味着要将其转换或翻译到目标格式。

对于进程间通信的 marshalling:一个线程不能简单地“调用”另一个线程——数据必须被打包并“发送”到另一个线程。Marshalling 是打包数据的过程(例如,关于要调用的方法及其参数的数据)。

如果您在进行互操作方面的 marshalling,则需要将方法调用及其参数打包成可以发送到运行 COM 组件的进程/线程的数据结构。该包需要以 COM 组件能够理解的格式进行。


10

来自维基百科 - 编组 (计算机科学):

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

当从.NET调用未托管的函数时,编组用于将.NET的数据转换成未托管函数可以使用的数据。例如,System.String是基于Unicode的,但该字符串可能需要转换为ANSI字符串以便传递给未托管的C函数。

对于线程,编组通常指将某些数据的所有权从一个线程转移到另一个线程。例如,程序有两个线程。第一个线程从网络中读取数据,第二个线程计算该数据。在网络线程读取一些数据后,它会将数据转移(即“编组”)到计算线程进行处理。它可能通过将数据写入两个线程之间共享的队列来实现。

在线程中的编组几乎总是涉及到正在编组的数据的同步。


就像将C#中的System.String转换为C中的ANSI字符串的具体示例一样,这比抽象的解释更有帮助。然而,对于C#中的自定义类型,比如一个类,你如何将其封送到C中呢? - zheng yu
1
具体细节不在评论范围内,但基本上您需要在C#中镜像您的C结构定义。您可以在C#结构上使用一些属性(主要是StructLayout和MarshalAs),告诉.NET运行时如何编排结构的数据成员。请查看Marshaling Classes, Structures, and Unions获取一些示例和更多信息。 - Lee Berger

7
我理解的marshaling是提供了一种在不同操作环境下以一致的方式传输数据的方法。当将数据从托管代码转换到非托管代码时,情况大体相同。假设我有一些数据,例如一个整数数组或任何我选择的数据类型,并且我想在我的C++代码对其进行操作后,在我的C#代码中使用它。不能只是对C#代码说“嘿,这就是数组,请随意使用”。在C++中,int数组可能不以与C#相同的方式存储。Marshaling允许我们以独立于环境的方式传输数据,以便双方以完全相同的方式看到数据。另一个例子是在网络中。通常不称之为marshaling,但如果要通过网络传输,必须以某种方式传输,以便接收者以与发送者相同的方式解释数据。您的计算机可以按小端序表示数据,而其他计算机可以按大端序表示数据。总之,Marshaling为您提供了一种在不同操作环境下一致地表示数据的方法。

1

通常用于“以XML格式编写”的上下文中,但它可以转换为任何格式。

2.  To arrange, place, or set in methodical order.
   (from American Heritage® Dictionary of the English Language)

这意味着您正在按照所需的系统化顺序/格式排列数据。通常情况下,这是以XML格式进行的。


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