ฉันรู้ว่าในแง่ของเทคนิคการกระจายหลายอย่าง (เช่น RPC) คำว่า "Marshaling" ถูกนำมาใช้ แต่ไม่เข้าใจว่ามันแตกต่างจาก Serialization อย่างไร พวกเขาทั้งสองแปลงวัตถุเป็นชุดของบิตหรือไม่
ฉันรู้ว่าในแง่ของเทคนิคการกระจายหลายอย่าง (เช่น RPC) คำว่า "Marshaling" ถูกนำมาใช้ แต่ไม่เข้าใจว่ามันแตกต่างจาก Serialization อย่างไร พวกเขาทั้งสองแปลงวัตถุเป็นชุดของบิตหรือไม่
คำตอบ:
เรียบเรียงและอนุกรมมีหลวมตรงกันในบริบทของการเรียกขั้นตอนระยะไกล แต่ความหมายที่แตกต่างกันเป็นเรื่องของเจตนา
โดยเฉพาะอย่างยิ่ง marshaling เป็นเรื่องเกี่ยวกับการรับพารามิเตอร์จากที่นี่ไปที่นั่นในขณะที่อนุกรมเป็นเรื่องเกี่ยวกับการคัดลอกข้อมูลที่มีโครงสร้างไปยังหรือจากรูปแบบดั้งเดิมเช่นไบต์สตรีม ในแง่นี้การทำให้เป็นอนุกรมเป็นวิธีการหนึ่งในการทำ marshaling ซึ่งมักจะใช้ความหมายของการส่งต่อค่า
นอกจากนี้ยังเป็นไปได้สำหรับวัตถุที่จะ marshaled โดยอ้างอิงในกรณีที่ข้อมูล "บนลวด" เป็นเพียงข้อมูลสถานที่สำหรับวัตถุต้นฉบับ อย่างไรก็ตามวัตถุดังกล่าวอาจยังคงคล้อยตามการจัดลำดับค่า
ตามที่ @Bill กล่าวถึงอาจมีข้อมูลเมตาเพิ่มเติมเช่นตำแหน่งฐานรหัสหรือแม้แต่รหัสการนำวัตถุไปใช้
I
การเปลี่ยนแปลงตัวพิมพ์ใหญ่และอื่น ๆ ตามความจำเป็น
ทั้งสองทำสิ่งเดียวกัน - นั่นคือการทำให้เป็นอันดับวัตถุ การทำให้เป็นอนุกรมใช้ในการถ่ายโอนวัตถุหรือเพื่อเก็บไว้ แต่:
การทำให้เป็นอันดับจึงเป็นส่วนหนึ่งของ Marshalling
CodeBaseเป็นข้อมูลที่บอกผู้รับของ Object ซึ่งสามารถนำไปใช้กับวัตถุนี้ได้ โปรแกรมใด ๆ ที่คิดว่าอาจส่งผ่านวัตถุไปยังโปรแกรมอื่นที่อาจไม่เคยเห็นมาก่อนจะต้องตั้งรหัสฐานเพื่อให้ผู้รับสามารถทราบได้ว่าจะดาวน์โหลดรหัสจากที่ใดหากไม่มีรหัสอยู่ในเครื่อง ผู้รับจะทำการดึงรหัสฐานออกจากวัตถุและทำการโหลดรหัสจากตำแหน่งนั้น
invokeAndWait
and Forms's Invoke
ซึ่งจะทำการซิงโครนัสการเรียกไปยังเธรด UI โดยไม่เกี่ยวข้องกับการทำให้เป็นอนุกรม
the implementation of this object
อะไร คุณสามารถยกตัวอย่างเฉพาะของSerialization
และMarshalling
?
จากบทความมาร์แชล (วิทยาการคอมพิวเตอร์) Wikipedia:
คำว่า "marshal" นั้นมีความหมายเหมือนกันกับ "serialize" ใน Python standard library 1แต่คำศัพท์ไม่ตรงกันใน RFC 2713 ที่เกี่ยวกับ Java:
ในการ "marshal" วัตถุหมายถึงการบันทึกสถานะและ codebase (s) ในลักษณะที่เมื่อวัตถุ marshalled คือ "unmarshalled" สำเนาของวัตถุต้นฉบับจะได้รับอาจโดยการโหลดคำจำกัดความของชั้นของวัตถุโดยอัตโนมัติ คุณสามารถจัดระเบียบวัตถุใด ๆ ที่เป็นอนุกรมหรือระยะไกล การมาร์แชลเป็นเหมือนการทำให้เป็นอนุกรมยกเว้นการจัดเรียงยังบันทึกรหัสฐาน การมาร์แชลมีความแตกต่างจากการทำให้เป็นอนุกรมในการจัดการกับวัตถุระยะไกลเป็นพิเศษ (RFC 2713)
ในการ "ซีเรียลไลซ์" วัตถุหมายถึงการแปลงสถานะเป็นสตรีมไบต์ในลักษณะที่สตรีมไบต์สามารถแปลงกลับเป็นสำเนาของวัตถุ
ดังนั้น marshalling ยังบันทึกcodebaseของวัตถุในสตรีมไบต์นอกเหนือจากสถานะ
ฉันคิดว่าความแตกต่างที่สำคัญคือมาร์แชลที่คาดคะเนยังเกี่ยวข้องกับ codebase กล่าวอีกนัยหนึ่งคุณจะไม่สามารถรวบรวมและยกเลิกการแยกวัตถุออกเป็นอินสแตนซ์ที่เทียบเท่ากับสถานะของคลาสอื่น .
การทำให้เป็นอนุกรมหมายความว่าคุณสามารถเก็บวัตถุและรับสถานะที่เทียบเท่าได้อีกครั้งแม้ว่ามันจะเป็นอินสแตนซ์ของคลาสอื่น
ที่ถูกกล่าวว่าพวกเขามักจะมีความหมายเหมือนกัน
Marshaling หมายถึงการแปลงลายเซ็นและพารามิเตอร์ของฟังก์ชันเป็นอาร์เรย์ไบต์เดียว โดยเฉพาะสำหรับวัตถุประสงค์ของ RPC
การทำให้เป็นอันดับบ่อยขึ้นหมายถึงการแปลงทั้งวัตถุ / ต้นไม้วัตถุเป็นอาร์เรย์ไบต์ Marshaling จะทำให้เป็นอันดับพารามิเตอร์ของวัตถุเพื่อเพิ่มลงในข้อความและส่งผ่านเครือข่าย * การทำให้เป็นอนุกรมสามารถใช้สำหรับการจัดเก็บไปยังดิสก์ได้ *
มาร์แชลเป็นกฎที่บอกคอมไพเลอร์ว่าข้อมูลจะถูกแสดงในสภาพแวดล้อม / ระบบอื่นได้อย่างไร ตัวอย่างเช่น;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
ในขณะที่คุณสามารถเห็นสองค่าสตริงที่แตกต่างกันแสดงเป็นประเภทค่าที่แตกต่างกัน
การทำให้เป็นอนุกรมจะแปลงเนื้อหาวัตถุเท่านั้นไม่ใช่การแสดง (จะยังคงเหมือนเดิม) และปฏิบัติตามกฎของการทำให้เป็นอนุกรม (สิ่งที่จะส่งออกหรือไม่) ตัวอย่างเช่นค่าส่วนตัวจะไม่ต่อเนื่องค่าสาธารณะใช่และโครงสร้างวัตถุจะยังคงเหมือนเดิม
นี่คือตัวอย่างที่ชัดเจนยิ่งขึ้นของทั้งสอง:
ตัวอย่างการทำให้เป็นอันดับ:
#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;
}
ในการทำให้เป็นอนุกรมข้อมูลจะถูกทำให้แบนในลักษณะที่สามารถจัดเก็บและไม่ถูกทำให้แบนภายหลังได้
การสาธิต Marshalling:
(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 ข้อมูลไม่จำเป็นต้องถูกทำให้แบน แต่จำเป็นต้องเปลี่ยนเป็นรูปแบบทางเลือกอื่น การหล่อทั้งหมดเป็น marshaling แต่ไม่ใช่การหล่อทั้งหมดจะเป็นการหล่อ
Marshaling ไม่ต้องการการจัดสรรแบบไดนามิกที่จะเกี่ยวข้อง แต่มันก็สามารถเป็นการเปลี่ยนแปลงระหว่าง structs ตัวอย่างเช่นคุณอาจมีคู่ แต่ฟังก์ชั่นคาดว่าองค์ประกอบแรกและสองของคู่จะเป็นวิธีอื่น ๆ คุณแคสต์ / 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 string" ให้คุณ แต่คุณสามารถขอให้มันพิมพ์ c สตริงที่ห่อหุ้มให้คุณได้ หรือถ้าคุณต้องการพิมพ์สตริงจาก JavaScript runtime ใน Lua หรือ Python runtime พวกเขาเป็นสตริงทั้งหมด แต่มักจะไม่เข้ากันได้หากปราศจากการจัดการ
สิ่งที่น่ารำคาญเมื่อเร็ว ๆ นี้คือ JScript ได้จัด marshal ไปยัง 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 #
อีกแนวคิดที่น่าสนใจคือคุณอาจมีความเข้าใจวิธีการเขียนโค้ดและคอมพิวเตอร์ที่รู้วิธีการใช้คำสั่งดังนั้นในฐานะโปรแกรมเมอร์คุณกำลังจัดวางแนวคิดของสิ่งที่คุณต้องการให้คอมพิวเตอร์ทำจากสมองถึงโปรแกรม ภาพ. หากเรามีเจ้าหน้าที่รักษาความปลอดภัยที่ดีพอเราสามารถคิดถึงสิ่งที่เราต้องการจะทำ / เปลี่ยนแปลงและโปรแกรมจะเปลี่ยนวิธีการดังกล่าวโดยไม่ต้องพิมพ์บนแป้นพิมพ์ ดังนั้นถ้าคุณมีวิธีเก็บการเปลี่ยนแปลงทางกายภาพทั้งหมดในสมองของคุณในเวลาไม่กี่วินาทีที่คุณต้องการเขียนเครื่องหมายอัฒภาคคุณสามารถรวบรวมข้อมูลนั้นเป็นสัญญาณเพื่อพิมพ์เครื่องหมายอัฒภาคได้
มาร์แชลเป็นปกติระหว่างกระบวนการที่เกี่ยวข้องอย่างใกล้ชิด; การทำให้เป็นอันดับไม่จำเป็นต้องมีความคาดหวังนั้น ดังนั้นเมื่อ marshalling data ระหว่างกระบวนการคุณอาจต้องการส่งการอ้างอิงไปยังข้อมูลที่อาจมีราคาแพงในการกู้คืนในขณะที่ serialization คุณจะต้องบันทึกมันทั้งหมดเพื่อสร้างวัตถุใหม่เมื่อ deserialized
ความเข้าใจของฉันเกี่ยวกับการจัดระเบียบแตกต่างจากคำตอบอื่น ๆ
อันดับ:
เมื่อต้องการสร้างหรือคืนรูปแบบรูปแบบลวดของกราฟวัตถุโดยใช้หลักการ
จอมพล:
เมื่อต้องการสร้างหรือคืนรูปแบบเส้นลวดของกราฟวัตถุโดยใช้ไฟล์การแมปเพื่อให้สามารถกำหนดผลลัพธ์เองได้ เครื่องมืออาจเริ่มต้นโดยยึดมั่นกับการประชุม แต่ความแตกต่างที่สำคัญคือความสามารถในการปรับแต่งผลลัพธ์
สัญญาการพัฒนาครั้งแรก:
มาร์แชลเป็นสิ่งสำคัญในบริบทของสัญญาการพัฒนาครั้งแรก
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).
Byte Stream - สตรีมเป็นลำดับของข้อมูล สตรีมอินพุต - อ่านข้อมูลจากแหล่งที่มา สตรีมเอาต์พุต - เขียนข้อมูลไปยัง desitnation Java Byte Streams ใช้เพื่อดำเนินการอินพุต / เอาต์พุตไบต์ต่อไบต์ (8bits ในเวลา) กระแสไบต์เหมาะสำหรับการประมวลผลข้อมูลดิบเช่นไฟล์ไบนารี Java Character Streams ถูกใช้เพื่อดำเนินการอินพุต / เอาต์พุต 2 ไบต์ในแต่ละครั้งเนื่องจากอักขระถูกเก็บไว้โดยใช้ Unicode conventions ใน Java ที่มี 2 ไบต์สำหรับอักขระแต่ละตัว สตรีมตัวละครมีประโยชน์เมื่อเราประมวลผลไฟล์ข้อความ (อ่าน / เขียน)
RMI (การเรียกใช้วิธีการระยะไกล) - API ที่ให้กลไกในการสร้างแอปพลิเคชันแบบกระจายในจาวา RMI อนุญาตให้อ็อบเจ็กต์เรียกใช้เมธอดบนอ็อบเจ็กต์ที่รันใน JVM อื่น
ทั้งการทำให้เป็นอันดับและมาร์แชลจะถูกใช้เป็นคำพ้อง นี่คือความแตกต่างเล็กน้อย
การทำให้เป็นอนุกรม - ข้อมูลสมาชิกของวัตถุถูกเขียนไปยังรูปแบบไบนารีหรือ Byte Stream (และจากนั้นสามารถเขียนในไฟล์ / หน่วยความจำ / ฐานข้อมูลเป็นต้น) ไม่มีข้อมูลเกี่ยวกับชนิดข้อมูลสามารถเก็บไว้ได้เมื่อสมาชิกข้อมูลวัตถุถูกเขียนลงในรูปแบบไบนารี
จัดสรร - วัตถุเนื่อง (เพื่อกระแส byte ในรูปแบบไบนารี) กับข้อมูลชนิด + Codebase ที่แนบมาและผ่านไปแล้ววัตถุระยะไกล (RMI) Marshalling จะแปลงประเภทข้อมูลเป็นแบบแผนการตั้งชื่อที่กำหนดไว้ล่วงหน้าเพื่อให้สามารถสร้างขึ้นใหม่ตามประเภทข้อมูลเริ่มต้น
การทำให้เป็นอันดับจึงเป็นส่วนหนึ่งของ Marshalling
CodeBaseเป็นข้อมูลที่บอกผู้รับของวัตถุที่สามารถนำไปปฏิบัติของวัตถุนี้ได้ โปรแกรมใด ๆ ที่คิดว่าอาจส่งผ่านวัตถุไปยังโปรแกรมอื่นที่อาจไม่เคยเห็นมาก่อนจะต้องตั้งรหัสฐานเพื่อให้ผู้รับสามารถทราบได้ว่าจะดาวน์โหลดรหัสจากที่ใดหากไม่มีรหัสอยู่ในเครื่อง ผู้รับจะทำการดึงรหัสฐานออกจากวัตถุและทำการโหลดรหัสจากตำแหน่งนั้น (คัดลอกมาจากคำตอบ @Nasir)
การทำให้เป็นอนุกรมนั้นเกือบจะเหมือนกับการถ่ายโอนข้อมูลหน่วยความจำที่โง่ของหน่วยความจำที่ใช้โดยวัตถุในขณะที่มาร์แชลจัดเก็บข้อมูลเกี่ยวกับชนิดข้อมูลที่กำหนดเอง
ในทางใด ๆ การทำให้เป็นอนุกรมดำเนินการ marshalling ด้วย implematation ของ pass-by-value เนื่องจากไม่มีข้อมูลของชนิดข้อมูลถูกส่งผ่านเพียงแค่รูปแบบดั้งเดิมจะถูกส่งผ่านไปยังกระแสไบต์
การทำให้เป็นอันดับอาจมีปัญหาบางอย่างที่เกี่ยวข้องกับ big-endian, small-endian ถ้ากระแสข้อมูลไหลจากระบบปฏิบัติการหนึ่งไปยังอีกระบบปฏิบัติการหนึ่งหากระบบปฏิบัติการที่แตกต่างกันมีวิธีการที่แตกต่างกันในการแสดงข้อมูลเดียวกัน ในทางกลับกันมาร์แชลล์ก็ดีในการโยกย้ายระหว่าง OS เพราะผลที่ได้คือการแสดงระดับที่สูงขึ้น
Marshaling ใช้กระบวนการทำให้เป็นอนุกรมจริง ๆ แล้ว แต่ความแตกต่างที่สำคัญคือในการทำให้เป็นอนุกรมข้อมูลสมาชิกเท่านั้นและวัตถุตัวเองได้รับอนุกรมไม่ใช่ลายเซ็น แต่ใน Marshalling Object + รหัสฐาน (การดำเนินการ) จะได้รับการเปลี่ยนเป็นไบต์
Marshalling เป็นกระบวนการแปลงวัตถุ java เป็นวัตถุ xml โดยใช้ JAXB เพื่อให้สามารถใช้ในบริการเว็บได้
คิดว่าพวกเขาเป็นคำพ้องความหมายทั้งสองมีผู้ผลิตที่ส่งเนื้อหาไปยังผู้บริโภค ... ในตอนท้ายของอินสแตนซ์จะถูกเขียนลงในไบต์สตรีมและส่วนอื่น ๆ ที่ตรงกันข้ามย้อนกลับและขึ้นกับอินสแตนซ์เดียวกัน
NB - java RMI ยังมีการรองรับการขนส่งคลาสที่หายไปจากผู้รับ ...