RPC와 같은 여러 분산 기술 측면에서 “마샬링”이라는 용어가 사용되지만 직렬화와 어떻게 다른지 이해하지 못합니다. 둘 다 객체를 일련의 비트로 변환하지 않습니까?
관련 :
답변
마샬링 및 직렬화는 원격 프로 시저 호출의 맥락에서 느슨하게 동의하지만 의도적으로 의미 상 다릅니다.
특히, 마샬링은 여기에서 거기로 매개 변수를 가져 오는 것이지만 직렬화는 구조화 된 데이터를 바이트 스트림과 같은 기본 형식으로 복사하거나 복사하는 것에 관한 것입니다. 이러한 의미에서 직렬화는 마샬링을 수행하는 수단 중 하나이며 일반적으로 값별 의미를 구현합니다.
객체가 참조에 의해 마샬링 될 수도 있으며,이 경우 “와이어상의”데이터는 단순히 원래 객체에 대한 위치 정보이다. 그러나 이러한 개체는 여전히 직렬화를 중요하게 생각할 수 있습니다.
@Bill이 언급했듯이 코드 기반 위치 또는 객체 구현 코드와 같은 추가 메타 데이터가있을 수 있습니다.
답변
둘 다 공통적으로 한 가지 일을합니다-그것은 객체를 직렬화 하는 것입니다. 직렬화는 객체를 전송하거나 저장하는 데 사용됩니다. 그러나:
- 직렬화 : 개체를 직렬화하면 해당 개체 내의 멤버 데이터 만 바이트 스트림에 기록됩니다. 실제로 객체를 구현하는 코드가 아닙니다.
- 마샬링 : 마샬링이라는 용어는 Object를 원격 객체 (RMI) 에 전달하는 것에 대해 이야기 할 때 사용됩니다 . Marshalling Object에서 직렬화 됨 (멤버 데이터가 직렬화 됨) + 코드베이스가 첨부됩니다.
직렬화는 마샬링의 일부입니다.
CodeBase 는이 객체의 구현을 찾을 수있는 곳의 Object 수신자에게 알려주는 정보입니다. 이전에 보지 못한 다른 프로그램으로 객체를 전달할 수 있다고 생각하는 프로그램은 코드베이스를 설정해야 코드를 로컬에서 사용할 수없는 경우 수신자가 코드를 다운로드 할 위치를 알 수 있습니다. 수신자는 객체를 직렬화 해제 할 때 객체에서 코드베이스를 가져와 해당 위치에서 코드를로드합니다.
답변
로부터 마샬링 (컴퓨터 과학) Wikipedia 기사 :
“marshal”이라는 용어는 Python 표준 라이브러리에서 “serialize”와 동의어로 간주됩니다 1 되지만 Java 관련 RFC 2713에서는 동의어가 아닙니다.
객체를 “마샬링”한다는 것은 마샬링 된 객체가 “비 마샬링”될 때 객체의 클래스 정의를 자동으로로드하여 원래 객체의 사본을 얻는 방식으로 상태 및 코드베이스를 기록하는 것을 의미합니다. 직렬화 가능하거나 원격 인 모든 오브젝트를 마샬링 할 수 있습니다. 마샬링은 코드베이스를 기록한다는 점을 제외하면 직렬화와 비슷합니다. 마샬링은 마샬링이 원격 객체를 특별히 처리한다는 점에서 직렬화와 다릅니다. (RFC 2713)
객체를 “직렬화”한다는 것은 바이트 스트림이 객체의 복사본으로 다시 변환 될 수있는 방식으로 상태를 바이트 스트림으로 변환하는 것을 의미합니다.
따라서 마샬링 은 객체 의 코드베이스 를 상태 외에도 바이트 스트림에 저장합니다 .
답변
주요 차이점은 Marshalling이 코드베이스와 관련이 있다고 생각합니다. 즉, 객체를 다른 클래스의 상태와 동등한 인스턴스로 마샬링 및 마샬링 해제 할 수 없습니다. .
직렬화는 객체가 다른 클래스의 인스턴스 인 경우에도 객체를 저장하고 동등한 상태를 다시 얻을 수 있음을 의미합니다.
즉, 일반적으로 동의어입니다.
답변
마샬링은 함수의 서명과 매개 변수를 단일 바이트 배열로 변환하는 것을 말합니다.
특히 RPC를 목적으로합니다.
직렬화는 종종 전체 객체 / 객체 트리를 바이트 배열로 변환하는 것을 말합니다.
Marshaling은 객체 매개 변수를 직렬화하여 메시지에 추가하고 네트워크를 통해 전달합니다.
* 직렬화는 디스크에 저장하기 위해 사용할 수있다. *
답변
마샬링 은 다른 환경 / 시스템에서 데이터가 표현되는 방식을 컴파일러에 알리는 규칙입니다. 예를 들어;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
두 개의 다른 문자열 값이 다른 값 유형으로 표시되는 것을 볼 수 있습니다.
직렬화 는 표현이 아닌 객체 내용 만 변환하고 (동일하게 유지됨) 직렬화 규칙을 준수합니다 (내보낼 항목 또는없는 항목). 예를 들어 개인 값은 직렬화되지 않으며 공개 값은 yes이며 개체 구조는 동일하게 유지됩니다.
답변
다음은 더 구체적인 예입니다.
직렬화 예 :
#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);
}
마샬링에서 데이터를 반드시 평면화 할 필요는 없지만 다른 대체 표현으로 변환해야합니다. 모든 캐스팅이 마샬링되지만 모든 마샬링이 캐스팅은 아닙니다.
마샬링에는 동적 할당이 필요하지 않으며 구조체 간의 변환 일 수도 있습니다. 예를 들어, 페어가있을 수 있지만이 함수는 페어의 첫 번째 요소와 두 번째 요소가 다른 방식 일 것으로 예상합니다. fst와 snd가 뒤집어지기 때문에 한 쌍을 다른 쌍으로 캐스팅 / memcpy하면 작업을 수행하지 않습니다.
#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;
}
마샬링의 개념은 여러 유형의 태그가 지정된 조합을 처리 할 때 특히 중요합니다. 예를 들어, “c 문자열”을 인쇄하기 위해 JavaScript 엔진을 얻는 것이 어려울 수 있지만 랩핑 된 c 문자열을 인쇄하도록 요청할 수 있습니다. 또는 Lua 또는 Python 런타임의 JavaScript 런타임에서 문자열을 인쇄하려는 경우. 그것들은 모두 문자열이지만 종종 마샬링하지 않고는 어울리지 않습니다.
최근에 JScript 배열이 C #에 “__ComObject”로 마샬링되어이 개체를 재생할 수있는 문서화 된 방법이 없었습니다. 나는 그것이 어디에 있는지에 대한 주소를 찾을 수 있지만, 나는 그것에 대해 다른 것을 전혀 모른다. 그래서 실제로 그것을 알아낼 수있는 유일한 방법은 가능한 어떤 방식 으로든 그것을 찌르고 그것에 대해 유용한 정보를 찾는 것입니다. 따라서 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 #의 관점에서 볼 때 다소 블랙 박스입니다.
또 다른 흥미로운 개념은 코드 작성 방법과 명령 실행 방법을 알고있는 컴퓨터에 대한 이해가있을 수 있으므로 프로그래머는 컴퓨터가 두뇌에서 프로그램으로 수행하려는 작업의 개념을 효과적으로 마샬링하는 것입니다 영상. 마샬 러가 충분하다면, 우리가하고 싶은 일 / 변경을 생각할 수있을뿐 아니라 키보드를 입력하지 않아도 프로그램이 변경 될 것입니다. 따라서 실제로 세미콜론을 작성하려는 몇 초 동안 뇌의 모든 신체적 변화를 저장할 수있는 방법이 있다면 해당 데이터를 신호에 마샬링하여 세미콜론을 인쇄 할 수는 있지만 극단적입니다.
