シリアル化とマーシャリングの違いは何ですか?


522

いくつかの分散技術(RPCなど)の観点からは、「マーシャリング」という用語が使用されていますが、シリアライゼーションとの違いがわかりません。どちらもオブジェクトを一連のビットに変換していませんか?

関連:

シリアライゼーションとは何ですか?

オブジェクトマーシャリングとは何ですか?

回答:


405

マーシャリングとシリアル化は、リモートプロシージャコールのコンテキストでは大まかに同義ですが、意図的には意味的に異なります。

特に、マーシャリングとは、ここからパラメータを取得することであり、シリアライゼーションとは、バイトストリームなどのプリミティブフォームとの間で構造化データをコピーすることです。この意味で、シリアル化はマーシャリングを実行する1つの手段であり、通常は値渡しのセマンティクスを実装します。

オブジェクトを参照でマーシャリングすることもできます。その場合、「ワイヤ上の」データは、元のオブジェクトの単なる位置情報です。ただし、そのようなオブジェクトはまだ値のシリアル化が可能です。

@Billが言及するように、コードベースの場所やオブジェクト実装コードなどの追加のメタデータが存在する場合があります。


3
同時にシリアライズとデシリアライズを意味する言葉はありますか?これらのメソッドとのインターフェースの名前が必要です。
ラフィアン

1
@raffian、シリアライゼーションとデシリアライゼーションを受けるオブジェクト、またはプロセスの管理を担当するオブジェクトによって実装されるインターフェースを意味しますか?私が提案するキーワードは、それぞれ「シリアライズ可能」と「フォーマッタ」です。I必要に応じて、先頭の、大文字の変更などで装飾します。
ジェフリーハンティン2014

@JeffreyHantinプロセスの管理を担当するオブジェクトは、私が意図したものです。私は今ISerializerを使用していますが、それはちょうど半分に過ぎません:)
ラフィアン

6
テレコミュニケーションの@raffianでは、 "SerDes"または "serdes"をシリアル化および逆シリアル化するコンポーネントを呼び出します。通常、好みに応じてsir-dezまたはsir-deezと発音します。その構造は「モデム」(つまり「Modulator-Demodulator」)に似ていると思います。
davidA

2
@naki業界全体-高速FPGAデータシートを見ると、それらはSERDES機能に言及していますが、これらはすべて1990年代に遡ってかなり現代的です。Google NGramsは、1970年代の
davidA

208

どちらも共通の1つのことを行います。つまり、オブジェクトのシリアル化です。シリアライゼーションは、オブジェクトの転送または保存に使用されます。だが:

  • シリアル化:オブジェクトをシリアル化すると、そのオブジェクト内のメンバーデータのみがバイトストリームに書き込まれます。実際にオブジェクトを実装するコードではありません。
  • マーシャリング:マーシャリングという 用語は、オブジェクトをリモートオブジェクト(RMI)に渡すことについて説明するときに使用されます。マーシャリングでは、オブジェクトがシリアル化されます(メンバーデータはシリアル化されます)+コードベースがアタッチされます。

したがって、シリアライゼーションはマーシャリングの一部です。

CodeBaseは、このオブジェクトの実装が見つかるObjectのレシーバーに通知する情報です。オブジェクトをこれまでに見たことがない可能性がある別のプログラムに渡す可能性があると考えるプログラムは、コードベースを設定する必要があります。これにより、ローカルで使用できるコードがない場合に、レシーバーがコードをダウンロードする場所を知ることができます。レシーバーは、オブジェクトをデシリアライズすると、オブジェクトからコードベースをフェッチし、その場所からコードをロードします。


45
このコンテキストでのCodeBaseの意味を定義するための+1
Omar Salem

2
シリアライゼーションなしのマーシャリングは起こります。Swing invokeAndWaitとFormsを参照してくださいInvoke。これらは、シリアル化を行わずにUIスレッドへの同期呼び出しをマーシャリングします。
ジェフリーハンティン

2
「実際にオブジェクトを実装するコードではない」:クラスメソッドを意味するのか またはこれはどういう意味ですか。説明していただけますか?
Vishal Anand

2
どういう意味the implementation of this objectSerializationandの具体例を教えてくださいMarshalling
Simin Jie

シリアル化なしのマーシャリングは、関数呼び出しが単一のプロセス内のスレッドモデル間(たとえば、共有スレッドプールとシングルピンスレッドライブラリ間)で制御フローを転送する場合など、一部のコンテキストで発生します。これが、RPCのコンテキストでは大まかに同義であると私が言う理由です。
ジェフリーハンティン

94

マーシャリング(コンピュータサイエンス)ウィキペディアの記事:

「マーシャル」という用語は、Python標準ライブラリ1では「シリアライズ」と同義と見なされていますが、Java関連のRFC 2713では同義ではありません。

オブジェクトを「マーシャリング」するとは、マーシャルされたオブジェクトが「アンマーシャリング」されたときに、おそらくオブジェクトのクラス定義を自動的にロードすることによって、元のオブジェクトのコピーが取得されるように、オブジェクトの状態とコードベースを記録することを意味します。シリアライズ可能またはリモートのオブジェクトをマーシャリングできます。マーシャリングはコードベースも記録することを除いて、シリアライゼーションに似ています。マーシャリングはシリアル化とは異なり、マーシャリングはリモートオブジェクトを特別に扱います。(RFC 2713)

オブジェクトを「シリアル化」するとは、バイトストリームをオブジェクトのコピーに変換できるように、オブジェクトの状態をバイトストリームに変換することです。

したがって、マーシャリングでは、オブジェクトの状態に加えて、オブジェクトのコードベースもバイトストリームに保存されます。


1
つまり、オブジェクトは、シリアル化されていない場合、状態のみを持つことができ、コードベースはありません。つまり、その関数を呼び出すことができず、構造化されたデータ型にすぎません。そして、同じオブジェクトがマーシャリングされている場合、構造と一緒にコードベースがあり、関数を呼び出すことができますか?
bjan

11
「コードベース」は実際には「コード」を意味しません。「コードベースのしくみ」(goo.gl/VOM2Ym)から、コードベースは、リモートクラスロードのRMIのセマンティクスを使用するプログラムが新しいクラスを見つける方法です。オブジェクトの送信者が別のJVMに送信するためにそのオブジェクトをシリアル化するとき、バイトのシリアル化されたストリームにコードベースと呼ばれる情報で注釈を付けます。この情報は、このオブジェクトの実装がどこにあるかをレシーバーに伝えます。コードベースアノテーションに格納される実際の情報は、必要なオブジェクトのクラスファイルをダウンロードできるURLのリストです。
Giuseppe Bertone 2014年

2
@Neuroneその定義は、JiniとRMIに固有のものです。「コードベース」は一般的な用語です。en.wikipedia.org/wiki/Codebase
Bill the Lizard、

2
@BilltheLizardええ、でも、Javaでのマーシャリングについて話しているので、シリアライゼーションとマーシャリングの違いは「マーシャリングによってオブジェクトのコードがその状態に加えて保存される」と言うのは誤りであり、bjanの質問につながります。マーシャリングは、オブジェクトの状態に加えて「コードベース」を保存します。
Giuseppe Bertone 2014年

19

主な違いは、マーシャリングにはおそらくコードベースも含まれるということです。つまり、オブジェクトを別のクラスの状態と同等のインスタンスにマーシャリングおよびアンマーシャリングすることはできません。。

シリアル化とは、別のクラスのインスタンスであっても、オブジェクトを格納して同等の状態を再取得できることを意味します。

そうは言っても、それらは通常同義語です。


2
オブジェクトがシリアル化されていない場合、単に状態を持つことができるということですか?コードベースはありません。つまり、その関数はどれも呼び出すことができず、単なる構造化データタイプです。また、同じオブジェクトがマーシャリングされている場合、コードベースと構造があり、その関数を呼び出すことができますか?
bjan

18

マーシャリングとは、関数のシグネチャとパラメーターを1バイト配列に変換することです。 特にRPCを目的としています。

より多くの場合、 シリアライゼーションとは、オブジェクト/オブジェクトツリー全体をバイト配列に変換することを指します。マーシャリングは、オブジェクトパラメータをシリアル化してメッセージに追加し、ネットワーク経由で渡します。 *シリアル化はディスクへの保存にも使用できます。*


11

マーシャリングは、データが別の環境/システムでどのように表されるかをコンパイラーに指示するルールです。例えば;

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

2つの異なる文字列値が異なる値の型として表されていることがわかります。

シリアライズシリアライズの唯一のオブジェクトの内容ではなく、表現に変換します(同じままになります)必ず従うルール、(どのような輸出へ、あるいはまったく)。たとえば、プライベート値はシリアル化されず、パブリック値はあり、オブジェクト構造は同じままです。


7

両方のより具体的な例を次に示します。

シリアル化の例:

#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);    
}

マーシャリングでは、データは必ずしもフラット化する必要はありませんが、別の代替表現に変換する必要があります。すべてのキャストはマーシャリングですが、すべてのマーシャリングがキャストしているわけではありません。

マーシャリングは動的な割り当てを必要とせず、構造体間の変換でもかまいません。たとえば、ペアがあるかもしれませんが、関数はペアの最初と2番目の要素が逆であることを期待しています。あるペアを別のペアにキャスト/ 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配列が "__ComObject"としてC#にマーシャリングし、このオブジェクトを操作するための文書化された方法がないことです。私はそれがどこにあるかのアドレスを見つけることができますが、それについて他に何も知らないので、それを実際に理解する唯一の方法は、可能な方法でそれをつついて、うまくいけばそれに関する有用な情報を見つけることです。そのため、Scripting.Dictionaryのような使いやすいインターフェイスで新しいオブジェクトを作成し、JScript配列オブジェクトからデータをコピーして、そのオブジェクトをJScriptの既定の配列ではなくC#に渡すことが簡単になります。

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);
        }
    }
}

上記では、C_の観点から見ると "__ComObject"を出力しますが、これはブラックボックスです。

もう1つの興味深い概念は、コードの記述方法と、命令の実行方法を知っているコンピューターを理解している可能性があるということです。したがって、プログラマーとして、コンピューターが脳からプログラムに実行することの概念を効果的に整理しています。画像。マーシャラーの数が十分であれば、やりたいことや変更したいことを考えれば、プログラムはキーボードで入力しなくてもそのように変更されます。したがって、セミコロンを実際に書き込みたい場所で、脳内のすべての物理的変化を数秒間保存できる方法がある場合、そのデータを信号にマーシャリングしてセミコロンを印刷できますが、これは極端です。


4

マーシャリングは通常、比較的密接に関連するプロセス間で行われます。シリアライゼーションは必ずしもその期待を持っているわけではありません。たとえば、プロセス間でデータをマーシャリングする場合は、コストがかかる可能性のあるデータにREFERENCEを送信するだけで回復できますが、シリアル化では、データをすべて保存して、逆シリアル化したときにオブジェクトを適切に再作成できます。


4

マーシャリングに対する私の理解は、他の答えとは異なります。

シリアル化:

慣習を利用して、オブジェクトグラフのワイヤー形式バージョンを生成または再水和します。

マーシャリング:

結果をカスタマイズできるように、マッピングファイルを使用してオブジェクトグラフのワイヤー形式バージョンを生成または再水和します。このツールは、慣例に従うことから始まる場合がありますが、重要な違いは、結果をカスタマイズする機能です。

契約優先開発:

マーシャリングは、契約優先開発のコンテキストにおいて重要です。

  • 外部インターフェイスを長期にわたって安定させながら、内部オブジェクトグラフに変更を加えることができます。この方法では、すべてのサービスサブスクライバーを、些細な変更ごとに変更する必要はありません。
  • 異なる言語間で結果をマッピングすることが可能です。たとえば、ある言語のプロパティ名の規則( 'property_name')から別の言語( 'propertyName')へ。

1
//、具体的には「再水和」の意味を詳しく教えてもらえますか。この回答では、@ JasperBluesですか?私はそれが宇宙飛行士の食物のためだけのものではないと思います。
Nathan Basanese

-この答えに応じて@NathanBasanese stackoverflow.com/a/6991192/5101816 - (再)水和の定義次の単語に含まれていますHydrating an object is taking an object that exists in memory, that doesn't yet contain any domain data ("real" data), and then populating it with domain data (such as from a database, from the network, or from a file system).
pxsx

3

基本から

バイトストリーム -ストリームは一連のデータです。入力ストリーム-ソースからデータを読み取ります。出力ストリーム-データを宛先に書き込みます。Java Byte Streamsは、バイト単位で入出力を実行するために使用されます(一度に8ビット)。バイトストリームは、バイナリファイルなどの生データの処理に適しています。Java文字ストリームは、一度に2バイトの入出力を実行するために使用されます。これは、文字がJavaのUnicode規則を使用して、各文字ごとに2バイトで格納されるためです。文字ストリームは、テキストファイルを処理(読み取り/書き込み)するときに役立ちます。

RMI(Remote Method Invocation)-Javaで分散アプリケーションを作成するメカニズムを提供するAPI。RMIにより、オブジェクトは別のJVMで実行されているオブジェクトのメソッドを呼び出すことができます。


シリアライゼーションマーシャリングはどちらも同義語として大まかに使用されています。ここにいくつかの違いがあります。

シリアル化 -オブジェクトのデータメンバーは、バイナリ形式またはバイトストリームに書き込まれます(その後、ファイル/メモリ/データベースなどに書き込むことができます)。オブジェクトデータメンバーがバイナリ形式で書き込まれると、データ型に関する情報は保持されません。

ここに画像の説明を入力してください

マーシャリング -オブジェクトは、データタイプ+コードベースを付加してシリアル化され(バイナリ形式のバイトストリームに)、リモートオブジェクト(RMI)が渡されます。マーシャリングは、データ型を所定の命名規則に変換して、初期のデータ型に関して再構築できるようにします。 ここに画像の説明を入力してください

したがって、シリアライゼーションはマーシャリングの一部です。

CodeBaseは、このオブジェクトの実装が見つかるObjectのレシーバーに通知する情報です。オブジェクトをこれまでに見たことがない可能性がある別のプログラムに渡す可能性があると考えるプログラムは、コードベースを設定する必要があります。これにより、ローカルで使用できるコードがない場合に、レシーバーがコードをダウンロードする場所を知ることができます。レシーバーは、オブジェクトをデシリアライズすると、オブジェクトからコードベースをフェッチし、その場所からコードをロードします。(@Nasirの回答からコピー)

シリアライゼーションは、オブジェクトが使用するメモリの愚かなメモリダンプとほとんど同じですが、マーシャリングは、カスタムデータ型に関する情報を格納します。

ある方法では、データ型の情報は渡されず、プリミティブ形式のみがバイトストリームに渡されるため、シリアライゼーションは値渡しの実装によるマーシャリングを実行します。

異なるOSが同じデータを表す別の手段を持っている場合、ストリームがあるOSから別のOSに流れる場合、シリアル化にはビッグエンディアン、スモールエンディアンに関連するいくつかの問題があるかもしれません。一方、マーシャリングは、結果がより高いレベルの表現になるため、OS間で移行するのに完全に適しています。


1

マーシャリングは実際にはシリアル化プロセスを使用しますが、主な違いは、シリアル化ではデータメンバーとオブジェクト自体が署名ではなくシリアル化されるだけでなく、マーシャリングオブジェクト+コードベース(その実装)でもバイトに変換されることです。

マーシャリングは、JAXBを使用してjavaオブジェクトをxmlオブジェクトに変換し、Webサービスで使用できるようにするプロセスです。


0

それらを同義語として考えてください。どちらも、コンシューマにデータを送信するプロデューサを持っています...インスタンスの最後のフィールドでは、バイトストリームに書き込まれ、もう一方の端では、同じインスタンスで逆向きに動作します。

注意-Java RMIには、受信者から欠落しているクラスのトランスポートのサポートも含まれています...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.