Serialization和Marshaling有什麼區別?

我知道,就幾種分佈式技術(如RPC)而言,使用術語「編組」但不理解它與序列化的區別。 它們不是都將對象轉換爲一系列位嗎? java

有關:

什麼是序列化? ios

什麼是對象編組? 程序員


#1樓

二者都有一個共同點 - 即序列化對象。 序列化用於傳輸對象或存儲它們。 但: 數組

  • 序列化:序列化對象時,只將該對象中的成員數據寫入字節流; 而不是實際實現對象的代碼。
  • 編組:當咱們討論將Object傳遞給遠程對象(RMI)時使用術語編組。 在編組對象中序列化(成員數據被序列化) +附加了代碼庫。

所以序列化是編組的一部分。 分佈式

CodeBase是告訴Object的接收者能夠找到該對象的實現的信息。 任何認爲它可能將對象傳遞給以前可能沒有看到它的另外一個程序的程序必須設置代碼庫,以便接收方能夠知道從哪裏下載代碼,若是它沒有本地可用的代碼。 在對對象進行反序列化時,接收器將從中獲取代碼庫並從該位置加載代碼。 函數


#2樓

我對編組的理解與其餘答案不一樣。 工具

連載: ui

使用約定生成或從新水化對象圖的線格式版本。 spa

編組: code

使用映射文件生成或從新生成對象圖的線型版本,以即可以自定義結果。 該工具能夠從遵照慣例開始,但重要的區別在於自定義結果的能力。

合同優先發展:

在合同首次開發的背景下,編組很重要。

  • 它能夠對內部對象圖進行更改,同時保持外部接口隨時間穩定。 這樣,沒必要爲每一個微不足道的變化修改全部服務訂戶。
  • 能夠跨不一樣語言映射結果。 例如,從一種語言('property_name')的屬性名稱約定到另外一種語言('propertyName')。

#3樓

編組是告訴編譯器如何在另外一個環境/系統上表示數據的規則; 例如;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;

由於您能夠看到兩個不一樣的字符串值表示爲不一樣的值類型。

序列化只會轉換對象內容,而不是表示(將保持相同)並遵照序列化規則,(導出或不導出)。 例如,私有值不會被序列化,公共值爲yes,對象結構將保持不變。


#4樓

如下是兩個更具體的例子:

序列化示例:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef struct {
    char value[11];
} SerializedInt32;

SerializedInt32 SerializeInt32(int32_t x) 
{
    SerializedInt32 result;

    itoa(x, result.value, 10);

    return result;
}

int32_t DeserializeInt32(SerializedInt32 x) 
{
    int32_t result;

    result = atoi(x.value);

    return result;
}

int main(int argc, char **argv)
{    
    int x;   
    SerializedInt32 data;
    int32_t result;

    x = -268435455;

    data = SerializeInt32(x);
    result = DeserializeInt32(data);

    printf("x = %s.\n", data.value);

    return result;
}

在序列化中,數據以能夠在之後存儲和不平坦的方式展平。

編組演示:

(MarshalDemoLib.cpp)

#include <iostream>
#include <string>

extern "C"
__declspec(dllexport)
void *StdCoutStdString(void *s)
{
    std::string *str = (std::string *)s;
    std::cout << *str;
}

extern "C"
__declspec(dllexport)
void *MarshalCStringToStdString(char *s)
{
    std::string *str(new std::string(s));

    std::cout << "string was successfully constructed.\n";

    return str;
}

extern "C"
__declspec(dllexport)
void DestroyStdString(void *s)
{
    std::string *str((std::string *)s);
    delete str;

    std::cout << "string was successfully destroyed.\n";
}

(MarshalDemo.c)

#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main(int argc, char **argv)
{
    void *myStdString;

    LoadLibrary("MarshalDemoLib");

    myStdString = ((void *(*)(char *))GetProcAddress (
        GetModuleHandleA("MarshalDemoLib"),
        "MarshalCStringToStdString"
    ))("Hello, World!\n");

    ((void (*)(void *))GetProcAddress (
        GetModuleHandleA("MarshalDemoLib"),
        "StdCoutStdString"
    ))(myStdString);

    ((void (*)(void *))GetProcAddress (
        GetModuleHandleA("MarshalDemoLib"),
        "DestroyStdString"
    ))(myStdString);    
}

在編組中,數據不必定須要展平,但須要將其轉換爲另外一種替表明示。 全部的鑄造都是編組,但並不是全部的編組都是鑄造。

Marshaling不須要涉及動態分配,它也能夠只是結構之間的轉換。 例如,您可能有一對,但該函數指望該對的第一個和第二個元素是相反的; 你將一對轉換成memcpy對另外一對將沒法完成這項工做,由於fst和snd會被翻轉。

#include <stdio.h>

typedef struct {
    int fst;
    int snd;
} pair1;

typedef struct {
    int snd;
    int fst;
} pair2;

void pair2_dump(pair2 p)
{
    printf("%d %d\n", p.fst, p.snd);
}

pair2 marshal_pair1_to_pair2(pair1 p)
{
    pair2 result;
    result.fst = p.fst;
    result.snd = p.snd;
    return result;
}

pair1 given = {3, 7};

int main(int argc, char **argv)
{    
    pair2_dump(marshal_pair1_to_pair2(given));

    return 0;
}

當你開始處理許多類型的標記聯合時,編組的概念變得尤其重要。 例如,您可能會發現很難讓JavaScript引擎爲您打印「c字符串」,但您能夠要求它爲您打印一個包裝的c字符串。 或者,若是要在Lua或Python運行時中從JavaScript運行時打印字符串。 它們都是字符串,但若是沒有編組,每每不會相處。

我最近遇到的煩惱是,JScript數組將C#編組爲「__ComObject」,而且沒有記錄的方式來使用此對象。 我能夠找到它所在的地址,但我真的不知道其餘任何事情,因此真正弄明白的惟一方法是以任何可能的方式戳它並但願找到有關它的有用信息。 所以,使用更友好的界面(如Scripting.Dictionary)建立新對象變得更加容易,將JScript數組對象中的數據複製到其中,並將該對象傳遞給C#而不是JScript的默認數組。

test.js:

var x = new ActiveXObject("Dmitry.YetAnotherTestObject.YetAnotherTestObject");

x.send([1, 2, 3, 4]);

YetAnotherTestObject.cs

using System;
using System.Runtime.InteropServices;

namespace Dmitry.YetAnotherTestObject
{
    [Guid("C612BD9B-74E0-4176-AAB8-C53EB24C2B29"), ComVisible(true)]
    public class YetAnotherTestObject
    {
        public void send(object x)
        {
            System.Console.WriteLine(x.GetType().Name);
        }
    }
}

上面打印「__ComObject」,從C#的角度來看,它有點像黑盒子。

另外一個有趣的概念是你可能已經理解了如何編寫代碼,以及知道如何執行指令的計算機,所以做爲程序員,你有效地整理了你但願計算機從你的大腦到程序作什麼的概念。圖片。 若是咱們有足夠好的marshallers,咱們能夠想到咱們想要作什麼/改變什麼,而且程序會改變這種方式而無需在鍵盤上打字。 因此,若是你有辦法在你真正想要編寫分號的幾秒鐘內存儲大腦中的全部物理變化,你能夠將這些數據編組成一個信號來打印分號,但這是極端的。


#5樓

Marshaling實際上使用了序列化過程,但主要區別在於它僅在序列化中僅數據成員和對象自己被序列化而不是簽名,但在編組對象+代碼庫(其實現)中也將轉換爲字節。

編組是使用JAXB將java對象轉換爲xml對象的過程,以即可以在Web服務中使用它。

相關文章
相關標籤/搜索