什么是序列化,为什么我们需要它?
我很难相信从C#发送一个int
到C代码时不能直接通过简单的起始和终止信号来传输32位数据,而需要进行序列化。为什么C#不能只将这32位数据发送给C代码并告诉它这是一个int
呢?
如果有任何关于为什么我们需要序列化以及如何使用它的好教程或网站,请分享一下。
什么是序列化,为什么我们需要它?
我很难相信从C#发送一个int
到C代码时不能直接通过简单的起始和终止信号来传输32位数据,而需要进行序列化。为什么C#不能只将这32位数据发送给C代码并告诉它这是一个int
呢?
如果有任何关于为什么我们需要序列化以及如何使用它的好教程或网站,请分享一下。
由于不同的语言和环境具有不同的调用约定、布局约定、基元大小(例如 C# 中的 char
和 C 中的 char
)、不同的对象创建/销毁约定和不同的设计准则。你需要一种方法将托管代码的数据传输到非托管代码中并反之亦然,以便它们能够看到和理解彼此。这就是所谓的“marshalling”。
.NET代码(C#,VB)之所以称为“托管代码”,是因为它受到CLR (通用语言运行时)的“管理”。
如果您使用C或C ++或汇编语言编写代码,则称其为“非托管代码”,因为没有涉及CLR。您需要负责所有内存分配/释放。
驱动是连接托管代码和非托管代码的过程之一; 这是CLR提供的最重要服务之一。
将一个 int
进行序列化最理想的情况就是如你所说:将其从CLR的托管堆栈中复制到C代码可以访问的某个地方。而序列化字符串、对象、数组和其他类型则是比较困难的事情。
但是P/Invoke互操作层几乎为你处理了所有这些事情。
正如Vinko在评论中所说,您可以传递原始类型而不需要任何特殊的编组。这些称为“可平坦化”类型,包括byte、short、int、long等类型及其无符号对应类型。
此页面包含可平坦化和不可平坦化类型列表。
Marshalling(编组)是一种“媒介”,或者说是一种通往非托管世界数据类型的网关,反之亦然。通过使用PInvoke(平台调用),它可以确保以安全的方式返回数据。
Marshalling(编组)是将函数签名传递给位于不同机器上的另一个进程,通常通过将结构化数据转换为专用格式来实现,该格式可以传输到其他处理器系统(序列化/反序列化)。