いくつかの分散技術(RPCなど)の観点からは、「マーシャリング」という用語が使用されていますが、シリアライゼーションとの違いがわかりません。どちらもオブジェクトを一連のビットに変換していませんか?
いくつかの分散技術(RPCなど)の観点からは、「マーシャリング」という用語が使用されていますが、シリアライゼーションとの違いがわかりません。どちらもオブジェクトを一連のビットに変換していませんか?
回答:
マーシャリングとシリアル化は、リモートプロシージャコールのコンテキストでは大まかに同義ですが、意図的には意味的に異なります。
特に、マーシャリングとは、ここからパラメータを取得することであり、シリアライゼーションとは、バイトストリームなどのプリミティブフォームとの間で構造化データをコピーすることです。この意味で、シリアル化はマーシャリングを実行する1つの手段であり、通常は値渡しのセマンティクスを実装します。
オブジェクトを参照でマーシャリングすることもできます。その場合、「ワイヤ上の」データは、元のオブジェクトの単なる位置情報です。ただし、そのようなオブジェクトはまだ値のシリアル化が可能です。
@Billが言及するように、コードベースの場所やオブジェクト実装コードなどの追加のメタデータが存在する場合があります。
I
必要に応じて、先頭の、大文字の変更などで装飾します。
どちらも共通の1つのことを行います。つまり、オブジェクトのシリアル化です。シリアライゼーションは、オブジェクトの転送または保存に使用されます。だが:
したがって、シリアライゼーションはマーシャリングの一部です。
CodeBaseは、このオブジェクトの実装が見つかるObjectのレシーバーに通知する情報です。オブジェクトをこれまでに見たことがない可能性がある別のプログラムに渡す可能性があると考えるプログラムは、コードベースを設定する必要があります。これにより、ローカルで使用できるコードがない場合に、レシーバーがコードをダウンロードする場所を知ることができます。レシーバーは、オブジェクトをデシリアライズすると、オブジェクトからコードベースをフェッチし、その場所からコードをロードします。
invokeAndWait
とFormsを参照してくださいInvoke
。これらは、シリアル化を行わずにUIスレッドへの同期呼び出しをマーシャリングします。
the implementation of this object
?Serialization
andの具体例を教えてくださいMarshalling
。
マーシャリング(コンピュータサイエンス)ウィキペディアの記事:
「マーシャル」という用語は、Python標準ライブラリ1では「シリアライズ」と同義と見なされていますが、Java関連のRFC 2713では同義ではありません。
オブジェクトを「マーシャリング」するとは、マーシャルされたオブジェクトが「アンマーシャリング」されたときに、おそらくオブジェクトのクラス定義を自動的にロードすることによって、元のオブジェクトのコピーが取得されるように、オブジェクトの状態とコードベースを記録することを意味します。シリアライズ可能またはリモートのオブジェクトをマーシャリングできます。マーシャリングはコードベースも記録することを除いて、シリアライゼーションに似ています。マーシャリングはシリアル化とは異なり、マーシャリングはリモートオブジェクトを特別に扱います。(RFC 2713)
オブジェクトを「シリアル化」するとは、バイトストリームをオブジェクトのコピーに変換できるように、オブジェクトの状態をバイトストリームに変換することです。
したがって、マーシャリングでは、オブジェクトの状態に加えて、オブジェクトのコードベースもバイトストリームに保存されます。
主な違いは、マーシャリングにはおそらくコードベースも含まれるということです。つまり、オブジェクトを別のクラスの状態と同等のインスタンスにマーシャリングおよびアンマーシャリングすることはできません。。
シリアル化とは、別のクラスのインスタンスであっても、オブジェクトを格納して同等の状態を再取得できることを意味します。
そうは言っても、それらは通常同義語です。
マーシャリングは、データが別の環境/システムでどのように表されるかをコンパイラーに指示するルールです。例えば;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
2つの異なる文字列値が異なる値の型として表されていることがわかります。
シリアライズシリアライズの唯一のオブジェクトの内容ではなく、表現に変換します(同じままになります)必ず従うルール、(どのような輸出へ、あるいはまったく)。たとえば、プライベート値はシリアル化されず、パブリック値はあり、オブジェクト構造は同じままです。
両方のより具体的な例を次に示します。
シリアル化の例:
#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つの興味深い概念は、コードの記述方法と、命令の実行方法を知っているコンピューターを理解している可能性があるということです。したがって、プログラマーとして、コンピューターが脳からプログラムに実行することの概念を効果的に整理しています。画像。マーシャラーの数が十分であれば、やりたいことや変更したいことを考えれば、プログラムはキーボードで入力しなくてもそのように変更されます。したがって、セミコロンを実際に書き込みたい場所で、脳内のすべての物理的変化を数秒間保存できる方法がある場合、そのデータを信号にマーシャリングしてセミコロンを印刷できますが、これは極端です。
マーシャリングに対する私の理解は、他の答えとは異なります。
シリアル化:
慣習を利用して、オブジェクトグラフのワイヤー形式バージョンを生成または再水和します。
マーシャリング:
結果をカスタマイズできるように、マッピングファイルを使用してオブジェクトグラフのワイヤー形式バージョンを生成または再水和します。このツールは、慣例に従うことから始まる場合がありますが、重要な違いは、結果をカスタマイズする機能です。
契約優先開発:
マーシャリングは、契約優先開発のコンテキストにおいて重要です。
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).
バイトストリーム -ストリームは一連のデータです。入力ストリーム-ソースからデータを読み取ります。出力ストリーム-データを宛先に書き込みます。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間で移行するのに完全に適しています。