web-dev-qa-db-ja.com

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

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

関連:

シリアル化とは

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

434
Peter

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

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

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

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

337
Jeffrey Hantin

どちらも共通して1つのことを行います。つまり、オブジェクトをserializingします。シリアル化は、オブジェクトの転送または保存に使用されます。しかし:

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

つまり、シリアル化はマーシャリングの一部です。

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

160
Nasir Ali

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

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

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

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

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

90
Bill the Lizard

主な違いは、マーシャリングにはコードベースも含まれると思われることです。つまり、オブジェクトを別のクラスの状態に相当するインスタンスにマーシャリングおよびマーシャリング解除することはできません。 。

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

とはいえ、それらは通常同義語です。

18
Uri

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

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

17
H.Gankanda

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

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

異なる値タイプとして表される2つの異なる文字列値を見ることができます。

シリアル化は、表現ではなくオブジェクトのコンテンツのみを変換し(同じまま)、シリアル化のルールに従います(エクスポートするものまたはしないもの)。たとえば、プライベート値はシリアル化されず、パブリック値はyesになり、オブジェクト構造は変わりません。

9
Teoman shipahi

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

シリアル化の例:

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

上記は「__ComObject」を出力します。これは、C#の観点からはややブラックボックスです。

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

5
Dmitry

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

4
Paul Sonier

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

シリアル化:

規約を利用して、オブジェクトグラフのワイヤー形式バージョンを作成または復元します。

マーシャリング:

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

最初の開発契約:

マーシャリングは、コントラクトファースト開発のコンテキスト内で重要です。

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

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

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

0
Aman Goel

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

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

0
mP.