コンピュータサイエンスにおいて、マーシャリング(またはマーシャリング、米国式綴り)とは、オブジェクトのメモリ表現を、特に異なるランタイム間での保存や転送に適したデータ形式に変換するプロセスです。これは通常、コンピュータプログラムの異なる部分間、またはあるプログラムから別のプログラムへデータを移動する必要がある場合に使用されます。
マーシャリングは、プリミティブ オブジェクトに制限されるのではなく、複合オブジェクトを使用できるため、複雑な通信を簡素化します。
シリアル化との比較
マーシャリングはシリアル化と類似または同義ですが、技術的にはシリアル化はオブジェクトをマーシャリングするプロセスの 1 つのステップです。
- マーシャリングとは、クライアントからサーバーへ何らかのライブオブジェクトを転送する全体的な意図またはプロセスを指します(クライアントとサーバーは、任意の通信リンク(ソケット)の対応する端点にマッピングされる、抽象的でミラーリングされた概念とみなされます)。オブジェクトのマーシャリングのポイントは、ある実行中のプログラムに存在するオブジェクトを、別の実行中のプログラムにも存在させることです。つまり、クライアント上のオブジェクトをサーバーに転送するということです。これは、通信ソケット上で循環する中間のシリアル化された「ドライ」な表現(これは二の次ですが)を利用して、オブジェクトの構造、データ、および状態をランタイム間で移行できるようにする、一種の具体化です。
- シリアル化は、必ずしも同じ意図を持っているわけではありません。シリアル化は、データを変換してオブジェクトの中間的な「ドライ」表現 (たとえば、バイト ストリーム) を生成することのみを目的としており、この中間表現は別のランタイムで具体化されるか、データベース、ファイル、またはメモリに単純に保存されます。
マーシャリングとシリアル化は異なる方法で行われる場合もありますが、通常は何らかのシリアル化がマーシャリングに使用されます。[ 1 ]
デシリアライゼーションという用語は、サーバー側でドライオブジェクトをアンマーシャリングする、つまりデマーシャリング(またはアンマーシャリング)してライブオブジェクトに戻すことに似ています。つまり、シリアライズされたオブジェクトは内部データ構造、つまりターゲットランタイム内のライブオブジェクトに変換されます。これは通常、マーシャリングの正反対のプロセスに相当しますが、プロセスの両端で特定のビジネスロジックが実行される場合もあります。
マーシャリングの正確な定義は、Python、Java、.NETなどのプログラミング言語によって異なり、場合によってはシリアル化と同じ意味で使用されます。
さまざまなプログラミング言語でのマーシャリング
オブジェクトを「シリアル化」するとは、その状態をバイトストリームに変換し、そのバイトストリームをオブジェクトのコピーに再変換できるようにすることを意味します。これは本質的にはアンマーシャリングです。プログラミング言語によって、この2つの概念を区別するかどうかは異なります。いくつか例を挙げます。
Pythonでは、「マーシャル」という用語は、Python標準ライブラリ[ 2 ]における特定の種類の「シリアル化」、つまり内部Pythonオブジェクトの保存に使用されます。
marshal モジュールは主に、.pyc ファイルの Python モジュールの「疑似コンパイルされた」コードの読み書きをサポートするために存在します。
…
Pythonオブジェクトをシリアル化およびデシリアル化する場合は、代わりにpickleモジュールを使用してください。
— Python標準ライブラリ[ 3 ]
Java関連のRFC 2713では、オブジェクトをリモート呼び出し用にシリアル化する際にマーシャリングが使用されます。マーシャリングされたオブジェクトは、元のオブジェクトの状態を記録し、コードベースを含みます(ここでのコードベースとは、ソースコードではなく、オブジェクトコードをロードできるURLのリストを指します)。したがって、オブジェクトの状態とコードベースを変換するには、アンマーシャリングを行う必要があります。アンマーシャラーインターフェースは、コードベースを含むマーシャリングされたデータを、JAXBで実行可能なJavaオブジェクトに自動的に変換します。デシリアライズ可能なオブジェクトはすべてアンマーシャリングできます。ただし、逆は必ずしも真ではありません。
オブジェクトを「マーシャリング」するということは、その状態とコードベースを記録することを意味します。これにより、マーシャリングされたオブジェクトが「アンマーシャリング」されたときに、元のオブジェクトのコピーが取得されます。これは、オブジェクトのクラス定義を自動的にロードすることによって行われる場合もあります。シリアル化可能なオブジェクト、またはリモートオブジェクト(つまり、java.rmi.Remote インターフェースを実装しているオブジェクト)であれば、マーシャリングできます。マーシャリングはシリアル化に似ていますが、コードベースも記録します。マーシャリングはリモートオブジェクトを特別に扱うという点でシリアル化とは異なります。
…
[別のJava仮想マシン上のオブジェクトに対して] メソッドを呼び出すことができるオブジェクトはすべて、java.rmi.Remoteインターフェースを実装している必要があります。このようなオブジェクトが呼び出されると、その引数は整列化されてローカル仮想マシンからリモート仮想マシンに送信され、リモート仮想マシンでアン整列化されて使用されます。
— LDAPディレクトリ内のJavaオブジェクトを表現するためのスキーマ(RFC 2713)[ 4 ]
.NETでは、マーシャリングはリモート呼び出しを使用する際のシリアル化を指すためにも使用されます。
オブジェクトを値渡しすると、オブジェクトのコピーが作成され、サーバーにシリアル化されます。そのオブジェクトに対するメソッド呼び出しはすべてサーバー上で実行されます。
— Visual Basic .NETを使用してオブジェクトを値渡しでリモートサーバーにマーシャリングする方法(Q301116)[ 5 ]
使用法と例
マーシャリングは、プロセス間および/またはスレッド間でデータを転送する必要がある、さまざまなリモート プロシージャ コール(RPC) メカニズムの実装内で使用されます。
マイクロソフトのコンポーネントオブジェクトモデル(COM)では、COMアパートメントの境界を越えるときにインターフェイスポインターをマーシャリングする必要があります。[ 6 ] [ 7 ] .NET Frameworkでは、 P/Invokeプロセスのように、アンマネージ型とCLR型間の変換も、マーシャリングを必要とするアクションの例です。[ 8 ]
さらに、マーシャリングは、 Mozillaアプリケーションフレームワーク内で提供されるXPCOMテクノロジーを利用するスクリプトやアプリケーション内で広く使用されています。Mozilla Firefoxブラウザは、このフレームワークを使用して構築された人気のアプリケーションであり、スクリプト言語でXPConnect(Cross-Platform Connect)を介してXPCOMを利用できるようになっています。
例
Microsoft Windowsファミリのオペレーティング システムでは、Direct3D用のデバイス ドライバ セット全体がカーネル モード ドライバです。API のユーザー モード部分は、Microsoftが提供する DirectX ランタイムによって処理されます。
これは問題です。ユーザーモードからカーネルモード操作を呼び出すにはシステムコールを実行する必要があり、必然的にCPUは「カーネルモード」に切り替えざるを得なくなります。これは低速な操作であり、完了までにマイクロ秒単位の時間がかかります。[ 9 ]この間、CPUはいかなる操作も実行できません。したがって、この切り替え操作の実行回数を最小限に抑えることで、パフォーマンスを大幅に最適化できます。
Linux OpenGLドライバは、カーネルドライバとユーザー空間ドライバの2つに分かれています。ユーザー空間ドライバは、OpenGLコマンドをGPUに送信するマシンコードに変換する処理をすべて行います。システムコールの数を減らすため、ユーザー空間ドライバはマーシャリングを実装しています。GPUのコマンドバッファがレンダリングデータでいっぱいになった場合、APIは要求されたレンダリングコールを一時バッファに保存し、コマンドバッファが空に近づいた時点でカーネルモードに切り替え、保存されているコマンドを一括して追加することができます。
フォーマット
データをマーシャリングするには、シリアル化ターゲットとして選択される特定のデータ形式を活用した何らかのデータ転送が必要です。
XML と JSON と…
XMLはそのようなフォーマットの一つであり、システム間でデータを転送する手段です。例えば、MicrosoftはMicrosoft Officeスイートの様々なコンポーネント(Word、Excel、Access、PowerPointなど)のファイル形式の基盤としてXMLを使用しています(Office Open XMLを参照)。
これは通常、冗長な伝送形式となりますが、XMLの「開始タグ」と「終了タグ」が完全に括弧で囲まれた構文により、より正確な診断が可能になり、伝送エラーやディスクエラーからの復旧が容易になります。さらに、タグが繰り返し出現するため、標準的な圧縮方法を使用してコンテンツを縮小できます。すべてのOfficeファイル形式は、生のXMLを圧縮することで作成されます。[ 10 ] JSON (JavaScript Object Notation)などの代替形式はより簡潔ですが、エラー復旧の堅牢性はそれに応じて低くなります。
データがプログラムまたはアプリケーションに転送されると、使用するためにオブジェクトに戻す必要があります。そのため、アンマーシャリングは、リモートメソッド呼び出し(RMI)およびリモートプロシージャコール(RPC)メカニズムの実装の受信側で、送信されたオブジェクトを実行可能な形式にアンマーシャリングするために 一般的に使用されます。
ジャックスB
JAXB(Java Architecture for XML Binding)は、開発者がJavaオブジェクトのマーシャリングとアンマーシャリングを行うために使用する最も一般的なフレームワークです。JAXBは、Javaでサポートされている基本データ型と標準XMLスキーマデータ型間の相互変換を提供します。[ 11 ]
Xmlシリアライザー
XmlSerializerは、 C#開発者がC#オブジェクトのマーシャリングとアンマーシャリングに使用するフレームワークです。C#がJavaよりも優れている点の一つは、XmlSerializerクラスが含まれているため、C#がネイティブにマーシャリングをサポートしていることです。一方、Javaでは、マーシャリングをサポートするためにJAXBという非ネイティブなグルーコードが必要です。[ 12 ]
XMLから実行可能な表現へ
アンマーシャリングの例としては、オブジェクトのXML表現を、任意のプログラミング言語におけるオブジェクトのデフォルト表現に変換することが挙げられます。次のクラスを考えてみましょう。
public class Student { private char name [ 150 ] ; private int ID ; public String getName () { return this . name ; } public int getID () { return this . ID ; } void setName ( String name ) { this . name = name ; } void setID ( int ID ) { this . ID = ID ; } }- 特定のStudentオブジェクトの XML 表現:
<!-- コードスニペット 1 --><?xml version="1.0" encoding="UTF-8"?> <student id= "11235813" > <name>ジャヤラマン</name> </student> <student id= "21345589" > <name>シャム</name> </student>- Studentオブジェクトの実行可能な表現:
// コードスニペット2学生s1 =新しい学生(); s1 . setID ( 11235813 ); s1 . setName ( "Jayaraman" );学生s2 =新しい学生(); s2 . setID ( 21345589 ); s2 . setName ( "Shyam" );アンマーシャリングとは、コードスニペット1のXML表現をコードスニペット2のデフォルトの実行可能なJava表現に変換し、そのコードを実行して一貫性のあるライブオブジェクトを復元するプロセスです。異なる形式を選択した場合、アンマーシャリングのプロセスは異なりますが、ターゲットランタイムにおける最終結果は同じになります。
Javaでのアンマーシャリング
JAXBのアンマーシャラー
XMLデータを実行可能なJavaオブジェクトにアンマーシャリングする処理は、組み込みのUnmarshallerクラスによって行われます。Unmarshallerクラスで定義されているアンマーシャリングメソッドは、ファイル、FileInputStream、URLなど、様々な入力形式からXMLを受け入れるようにオーバーロードされています。 [ 13 ]例えば:
JAXBContext jcon = JAXBContext.newInstance ( "com.acme.foo" );アンマーシャラーumar = jcon.createUnmarshaller ( ); Object obj = umar.unmarshal ( new File ( " input.xml " ) ) ;XMLデータのアンマーシャリング
アンマーシャリングメソッドは、XML文書全体またはその一部をデシリアライズできます。XMLルート要素がグローバルに宣言されている場合、これらのメソッドはJAXBContextにおけるXMLルート要素とJAXBマップクラスとのマッピングを利用してアンマーシャリングを開始します。マッピングが不十分でルート要素がローカルに宣言されている場合、アンマーシャリングメソッドは宣言型メソッドを用いてアンマーシャリング処理を行います。これらの2つのアプローチについては、以下で説明します。[ 13 ]
グローバルXMLルート要素をアンマーシャルする
アンマーシャルメソッドは、ルート要素がグローバルに宣言されている場合、JAXBContextを使用してXMLデータをアンマーシャルします。JAXBContextオブジェクトは、グローバルに宣言されたXML要素とその名前をJAXBマップクラスにマッピングした情報を常に保持します。XML要素名またはその@xsi:type属性がJAXBマップクラスと一致する場合、アンマーシャルメソッドは適切なJAXBマップクラスを使用してXMLデータを変換します。ただし、XML要素名が一致しない場合、アンマーシャルプロセスは中止され、UnmarshalExceptionがスローされます。これは、宣言型によるアンマーシャルメソッドを使用することで回避できます。[ 14 ]
ローカルXMLルート要素をアンマーシャルする
ルート要素がグローバルに宣言されていない場合、アプリケーションは宣言型パラメータを用いたアプリケーション提供のマッピングによってアンマーシャラーを支援します。優先順位により、ルート名が適切なJAXBクラスへのマッピングを持つ場合でも、宣言型パラメータはそのマッピングをオーバーライドします。ただし、@xsi:typeXMLデータの属性が適切なJAXBクラスへのマッピングを持つ場合は、宣言型パラメータよりも優先されます。宣言型パラメータによるアンマーシャリングメソッドは常にJAXBElement<declaredType>インスタンスを返します。このJAXBElementインスタンスのプロパティは次のように設定されます。[ 15 ]
| JAXBElement プロパティ | 価値 |
|---|---|
| 名前 | XML要素名 |
| 価値 | 宣言された型のインスタンス |
| 宣言されたタイプ | unmarshal メソッドの宣言型パラメータ |
| 範囲 | null(実際のサイズは不明) |
参照
- 無料のオープンソースグラフィックデバイスドライバー#ソフトウェアアーキテクチャ
- コンポーネントオブジェクトモデル
- コルバ
- ピクルス(パイソン)
- プロトコルバッファ
- XMLバインディングのためのJavaアーキテクチャ
- 呼び出し規約
参考文献
- ^ Jeffrey Hantin. 「シリアル化とマーシャリングの違いは何ですか?」 . Stack Exchange Network . 2021年7月23日閲覧。
- ^ "marshal — Python内部オブジェクトのシリアル化" . Python Software Foundation . 2016年11月4日閲覧。
- ^ "marshal — Pythonオブジェクトの内部シリアル化" . Python Software Foundation . 2019年10月9日閲覧。
- ^ 「LDAPディレクトリ内のJavaオブジェクトを表すスキーマ」 IETF、1999年10月。 2016年11月4日閲覧。
- ^ 「Visual Basic .NETを使用してオブジェクトを値渡しでリモートサーバーにマーシャリングする方法」。Microsoft。2004年7月。2004年11月15日時点のオリジナルからアーカイブ。 2016年11月4日閲覧。
- ^ 「アパートメントとCOMスレッドモデル」 。 2015年9月23日時点のオリジナルよりアーカイブ。2009年6月19日閲覧。
- ^ 「CoInitializeEx関数(COM)」 . Windowsデスクトップアプリ開発. 2013年2月22日閲覧。
- ^相互運用マーシャリングの概要
- ^コード品質: オープンソースの観点。
- ^ DOCX ファイルとは何ですか? https://docs.fileformat.com/word-processing/docx/ 2020 年 10 月 13 日にアクセス。
- ^ 「XMLスキーマのバインディング - Java EE 5チュートリアル」 . docs.oracle.com . 2016年9月14日閲覧。
- ^ 「XmlSerializer クラスの使用」 . msdn.microsoft.com . 2016 年 9 月 23 日閲覧。
- ^ a b「Unmarshaller (JAXB 2.2.3)」 jaxb.java.net . 2012年6月5日時点のオリジナルよりアーカイブ。2016年9月14日閲覧。
- ^ "JAXBContext (JAXB 2.2.3)" . jaxb.java.net . 2016年9月27日時点のオリジナルよりアーカイブ。2016年9月23日閲覧。
- ^ "JAXBElement (JAXB 2.2.3)" . jaxb.java.net . 2013年2月16日時点のオリジナルよりアーカイブ。2016年9月23日閲覧。