В чем разница между сериализацией и маршалингом? - PullRequest
434 голосов
/ 21 апреля 2009

Я знаю, что в терминах нескольких распределенных методов (таких как RPC) используется термин «маршалинг», но не понимаю, чем он отличается от сериализации. Разве они оба не превращают объекты в серии битов?

* +1002 * Связанный:

Что такое сериализация?

Что такое Маршаллинг объектов?

Ответы [ 11 ]

337 голосов
/ 21 апреля 2009

Маршалинг и сериализация слабо синонимичны в контексте удаленного вызова процедуры, но семантически различаются в зависимости от намерения.

В частности, маршалинг - это получение параметров отсюда туда, а сериализация - копирование структурированных данных в или из примитивной формы, такой как поток байтов. В этом смысле сериализация является одним из способов выполнения маршалинга, обычно реализуя семантику передачи по значению.

Возможно также, что объект будет маршалироваться по ссылке, и в этом случае данные "на проводе" являются просто информацией о местоположении для исходного объекта. Тем не менее, такой объект все еще может быть поддается сериализации.

Как упоминает @Bill, могут существовать дополнительные метаданные, такие как расположение базы кода или даже код реализации объекта.

160 голосов
/ 02 февраля 2013

Оба делают одно общее - это сериализация объекта. Сериализация используется для передачи объектов или их хранения. Но:

  • Сериализация: При сериализации объекта в поток байтов записываются только данные члена этого объекта; не тот код, который фактически реализует объект.
  • Marshalling: Термин Marshalling используется, когда мы говорим о передаче объекта удаленным объектам (RMI) . В Marshalling Object сериализуется (данные члена сериализуются) + Кодовая база прикреплена.

Так что сериализация является частью Marshalling.

CodeBase - это информация, которая сообщает получателю объекта, где можно найти реализацию этого объекта. Любая программа, которая считает, что может когда-либо передать объект другой программе, которая, возможно, не видела его раньше, должна установить кодовую базу, чтобы получатель мог знать, откуда загрузить код, если у него нет кода, доступного локально. При десериализации объекта получатель извлечет из него кодовую базу и загрузит код из этого местоположения.

90 голосов
/ 21 апреля 2009

Из Marshalling (информатика) Статья в Википедии:

Термин «маршал» считается синонимом «сериализации» в стандартной библиотеке Python 1 , но эти термины не являются синонимами в RFC 2713, связанном с Java:

«Маршалировать» объект означает записывать его состояние и кодовую базу (ы) таким образом, чтобы, когда маршаллированный объект был «не маршалированным», получалась копия исходного объекта, возможно, путем автоматической загрузки определений классов предмет. Вы можете упорядочить любой объект, который можно сериализовать или удалить. Маршаллинг подобен сериализации, за исключением того, что маршаллинг также записывает кодовые базы. Маршаллинг отличается от сериализации тем, что маршаллинг специально обрабатывает удаленные объекты. (RFC 2713)

«Сериализация» объекта означает преобразование его состояния в поток байтов таким образом, что поток байтов может быть преобразован обратно в копию объекта.

Таким образом, сортировка также сохраняет код объекта в потоке байтов в дополнение к его состоянию.

18 голосов
/ 21 апреля 2009

Я думаю, что основное отличие состоит в том, что Marshalling предположительно также включает в себя кодовую базу. Другими словами, вы не сможете маршалировать и демаршировать объект в эквивалентный состоянию экземпляр другого класса. .

Сериализация просто означает, что вы можете сохранить объект и восстановить эквивалентное состояние, даже если это экземпляр другого класса.

При этом, как правило, они являются синонимами.

17 голосов
/ 08 октября 2011

Маршалинг относится к преобразованию сигнатуры и параметров функции в один байтовый массив. Специально для целей RPC.

Сериализация чаще всего относится к преобразованию всего дерева объектов / объектов в байтовый массив Marshaling будет сериализовать параметры объекта, чтобы добавить их в сообщение и передать его по сети. * Сериализация также может быть использована для хранения на диске. *

9 голосов
/ 12 марта 2015

Marshalling - это правило, сообщающее компилятору, как данные будут представлены в другой среде / системе; Например;

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

как вы видите два разных строковых значения, представленных в виде разных типов значений.

Сериализация будет конвертировать только содержимое объекта, а не представление (останется прежним) и подчиняться правилам сериализации (что экспортировать или нет). Например, частные значения не будут сериализованы, публичные значения yes и структура объекта останутся прежними.

4 голосов
/ 10 сентября 2017

Вот более конкретные примеры обоих:

Пример сериализации:

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

При маршалинге данные не обязательно должны быть сведены, но их необходимо преобразовать в другое альтернативное представление. весь кастинг является маршалингом, но не весь маршалинг кастингом.

Маршалинг не требует участия в динамическом распределении, он также может быть просто преобразованием между структурами. Например, у вас может быть пара, но функция ожидает, что первый и второй элементы пары будут другими; вы преобразуете / 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-строку. Или, если вы хотите напечатать строку из среды выполнения JavaScript в среде исполнения Lua или Python. Они все струнные, но часто не обходятся без маршалинга.

Недавно меня раздражало то, что JScript размещает маршал 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 # является чем-то вроде черного ящика.

Еще одна интересная концепция заключается в том, что у вас может быть понимание того, как писать код, и компьютер, который знает, как выполнять инструкции, так что, как программист, вы эффективно воплощаете концепцию того, что вы хотите, чтобы компьютер делал из своего мозга к образу программы. Если бы у нас было достаточно хороших маршаллеров, мы могли бы просто думать о том, что мы хотим сделать / изменить, и программа изменилась бы таким образом, не печатая на клавиатуре. Итак, если бы у вас был способ сохранить все физические изменения в вашем мозге в течение нескольких секунд, когда вы действительно хотите записать точку с запятой, вы могли бы преобразовать эти данные в сигнал для печати точки с запятой, но это крайность.

4 голосов
/ 21 апреля 2009

Маршаллинг обычно находится между относительно тесно связанными процессами; Сериализация не обязательно имеет такое ожидание. Так, например, при распределении данных между процессами вы можете просто послать ССЫЛКУ на потенциально дорогостоящие данные для восстановления, тогда как при сериализации вы хотели бы сохранить все это, чтобы правильно воссоздать объект (ы) после десериализации.

2 голосов
/ 25 июня 2014

Мое понимание сортировки отличается от других ответов.

Сериализация:

Создание или повторная гидрация версии графов объектов в формате с использованием соглашения.

Ранжирование:

Создание или повторная гидрация версии графов объектов в формате проводника с использованием файла сопоставления, чтобы можно было настроить результаты. Инструмент может начинаться с соблюдения соглашения, но важным отличием является возможность настройки результатов.

Первая контрактная разработка:

Маршаллинг важен в контексте первой контрактной разработки.

  • Можно вносить изменения во внутренний граф объектов, сохраняя стабильность внешнего интерфейса с течением времени. Таким образом, всем абонентам службы не нужно будет изменять каждое тривиальное изменение.
  • Возможно отобразить результаты на разных языках. Например, от соглашения имени свойства одного языка ('имя_свойства') к другому ('имя_свойства').
0 голосов
/ 14 ноября 2017

Маршалинг фактически использует процесс сериализации, но основное отличие состоит в том, что в сериализации только элементы данных и сам объект сериализуются не в сигнатурах, а в коде Marshalling Object + (его реализация) также преобразуется в байты.

Marshalling - это процесс преобразования java-объекта в xml-объекты с использованием JAXB, чтобы его можно было использовать в веб-службах.

...