725 Stimmen

Was ist der Unterschied zwischen Serialisierung und Marshaling?

Ich weiß, dass im Zusammenhang mit verschiedenen verteilten Techniken (z. B. RPC) der Begriff "Marshaling" verwendet wird, aber ich verstehe nicht, worin der Unterschied zur Serialisierung besteht. Werden nicht beide Objekte in eine Reihe von Bits umgewandelt?

Verwandt:

Was ist Serialisierung?

Was ist Object Marshalling?

21voto

H.Gankanda Punkte 207

Marshaling bedeutet, dass die Signatur und die Parameter einer Funktion in ein einzelnes Byte-Array umgewandelt werden. Speziell für die Zwecke der RPC.

Die Serialisierung bezieht sich eher auf die Umwandlung eines ganzen Objekts / Objektbaums in ein Byte-Array Beim Marshaling werden Objektparameter serialisiert, um sie der Nachricht hinzuzufügen und sie über das Netz zu übertragen. *Serialisierung kann auch für die Speicherung auf Festplatte verwendet werden.

16voto

Teoman shipahi Punkte 45327

rangieren. ist die Regel, die dem Compiler mitteilt, wie die Daten in einer anderen Umgebung/einem anderen System dargestellt werden sollen; Zum Beispiel;

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

wie Sie sehen können, werden zwei verschiedene Zeichenfolgenwerte als unterschiedliche Werttypen dargestellt.

Serialisierung konvertiert nur den Objektinhalt, nicht die Darstellung (bleibt gleich) und befolgt die Regeln der Serialisierung (was zu exportieren ist oder nicht). Zum Beispiel werden private Werte nicht serialisiert, öffentliche Werte ja und die Objektstruktur bleibt gleich.

9voto

Dmitry Punkte 4722

Hier finden Sie genauere Beispiele für beides:

Beispiel für Serialisierung:

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

Bei der Serialisierung werden die Daten so flach gemacht, dass sie gespeichert und später wieder entflacht werden können.

Marshalling Demo:

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

Beim Marshaling müssen die Daten nicht unbedingt reduziert werden, aber sie müssen in eine andere Darstellung umgewandelt werden.

Marshaling erfordert keine dynamische Zuweisung beteiligt zu sein, kann es auch nur Transformation zwischen Strukturen sein. Zum Beispiel könnten Sie ein Paar haben, aber die Funktion erwartet, dass das erste und zweite Element des Paares andersherum sind; Sie casting/memcpy ein Paar zu einem anderen wird nicht die Arbeit tun, weil fst und snd umgedreht werden.

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

Das Konzept des Marshaling wird besonders wichtig, wenn man mit vielen Arten von Tagged Unions zu tun hat. So ist es zum Beispiel schwierig, eine JavaScript-Engine dazu zu bringen, einen "c-String" für Sie zu drucken, aber Sie können sie bitten, einen "wrapped c-String" für Sie zu drucken. Oder wenn Sie eine Zeichenkette von der JavaScript-Laufzeit in einer Lua- oder Python-Laufzeit ausgeben wollen. Das sind alles Strings, aber oft kommen sie nicht ohne Marshaling aus.

Ein Ärgernis, das ich vor kurzem hatte war, dass JScript Arrays Marshal zu C# als "__ComObject", und hat keine dokumentierte Möglichkeit, mit diesem Objekt zu spielen. Ich kann die Adresse finden, wo es ist, aber ich weiß wirklich nichts anderes darüber, so dass der einzige Weg, um es wirklich herauszufinden, ist es in irgendeiner Weise möglich zu stochern und hoffentlich nützliche Informationen über sie zu finden. So wird es einfacher, ein neues Objekt mit einer freundlicheren Schnittstelle wie Scripting.Dictionary zu erstellen, die Daten aus dem JScript-Array-Objekt hineinzukopieren und dieses Objekt anstelle des Standard-Arrays von JScript an C# zu übergeben.

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

oben gibt "__ComObject" aus, was aus Sicht von C# so etwas wie eine Blackbox ist.

Ein weiteres interessantes Konzept besteht darin, dass Sie vielleicht wissen, wie man Code schreibt, und einen Computer haben, der weiß, wie man Anweisungen ausführt, so dass Sie als Programmierer das Konzept dessen, was der Computer tun soll, von Ihrem Gehirn auf das Programmbild übertragen. Hätten wir genügend gute Marshaller, könnten wir einfach daran denken, was wir tun/ändern wollen, und das Programm würde sich entsprechend ändern, ohne auf der Tastatur herumtippen zu müssen. Wenn Sie also eine Möglichkeit hätten, alle physikalischen Veränderungen in Ihrem Gehirn für die wenigen Sekunden zu speichern, in denen Sie wirklich ein Semikolon schreiben wollen, könnten Sie diese Daten in ein Signal zum Drucken eines Semikolons umwandeln, aber das ist ein Extrem.

4voto

Paul Sonier Punkte 37609

Das Marshalling findet in der Regel zwischen relativ eng verbundenen Prozessen statt; bei der Serialisierung ist das nicht unbedingt der Fall. Beim Marshalling von Daten zwischen Prozessen kann es beispielsweise sinnvoll sein, lediglich einen REFERENCE auf potenziell teure Daten zu senden, die wiederhergestellt werden müssen, wohingegen bei der Serialisierung alle Daten gespeichert werden sollten, um das/die Objekt(e) bei der Deserialisierung ordnungsgemäß wiederherzustellen.

4voto

Jasper Blues Punkte 27710

Ich verstehe unter Rangieren etwas anderes als die anderen Antworten.

Serialisierung:

Erzeugen oder Rehydrieren einer Drahtformatversion eines Objektgraphen unter Verwendung einer Konvention.

Marschieren:

Erzeugen oder Rehydrieren einer Drahtformatversion eines Objektgraphen unter Verwendung einer Mapping-Datei, so dass die Ergebnisse angepasst werden können. Das Werkzeug kann mit der Einhaltung einer Konvention beginnen, aber der wichtige Unterschied ist die Möglichkeit, die Ergebnisse anzupassen.

Contract First Development:

Das Marshalling ist im Rahmen der ersten Vertragsentwicklung wichtig.

  • Es ist möglich, Änderungen an einem internen Objektgraphen vorzunehmen, während die externe Schnittstelle im Laufe der Zeit stabil bleibt. Auf diese Weise müssen nicht alle Abonnenten des Dienstes bei jeder trivialen Änderung angepasst werden.
  • Es ist möglich, die Ergebnisse auf verschiedene Sprachen zu übertragen. Zum Beispiel von der Eigenschaftsnamenskonvention einer Sprache ('property_name') zu einer anderen ('propertyName').

1 Stimmen

// Darf ich mehr darüber erfahren, was genau "rehydrieren" in dieser Antwort bedeutet, @JasperBlues? Ich nehme an, es ist nicht nur für Astronautenfutter.

1 Stimmen

@NathanBasanese laut dieser Antwort - stackoverflow.com/a/6991192/5101816 - Die Definition des Begriffs (Re-)Hydratisierung lautet wie folgt: 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).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X