Entwickler-Ecke

IO, XML und Registry - Größe einer Variable für Umwandlung in Byte[] ermitteln


Xo-mate - Di 25.03.08 21:43
Titel: Größe einer Variable für Umwandlung in Byte[] ermitteln
Hi.
Ich habe folgendes Problem. Ich möchte eine Variable eines eigenen structs in Bytes umwandeln. Das Problem ist, dass sizeof(testclass) folgenden Fehler liefert (schon beim compilen):
Zitat:
Cannot take the address of, get the size of, or declare a pointer to a managed type ('Testcenter.testclass')


Marshal.SizeOf(test) liefert zur Laufzeit diesen Fehler:
Es kann keine sinnvolle Größe oder sinnvoller Offset berechnet werden, da der Typ Testcenter.testclass nicht als nicht verwaltete Struktur gemarshallt werden kann.

Brauchen tue ich das für diesen Codepart:

C#-Quelltext
1:
2:
3:
testclass msc = toCheck;
byte[] buffer = new byte[/*HIER DIE GRÖßE*/];
MemoryStream outputStream = new MemoryStream(buffer);


Moderiert von user profile iconChristian S.: C#- und Quote-Tags hinzugefügt
Moderiert von user profile iconChristian S.: Topic aus Allgemeine .NET-Fragen verschoben am Di 25.03.2008 um 21:50


Christian S. - Di 25.03.08 21:51

Wie sieht die Struktur denn aus? Ist die anständig serialisierbar?


Kha - Di 25.03.08 22:27
Titel: Re: Größe einer Variable für Umwandlung in Byte[] ermitteln
Zusätzlich zu Christians Frage:
Wo verwendest du den Stream? Wenn es nicht um Interop geht, gibt es im Framework meist eine bessere, managed Lösung.


Xo-mate - Mi 26.03.08 09:56

die teststruktur sieht derzeit so aus, soll aber später natürlich (teils erheblich) erweitert werden:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
[Serializable()]
class testclass
{
  int _testint = 1;
  int _teststr = "test";

  public testint 
  {
    set { _testint = value; }
    get { return (_testint); }
  }

  public teststr 
  {
    set { _teststr = value; }
    get { return (_teststr); }
  }
}


Den Stream verwende ich anschließend.
Hier die komplette "Variable to byte[]"-Prozedur:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
        private byte[] convertField(testclass toCheck)
        {
            testclass msc = toCheck;
            BinaryFormatter binFormatter = new BinaryFormatter();                        

            byte[] buffer = new byte[/*DIE GRÖßE*/];
            MemoryStream outputStream = new MemoryStream(buffer);
            
            binFormatter.Serialize(outputStream, msc);
            outputStream.Close();

            return (buffer);
        }


Kha - Mi 26.03.08 11:58

user profile iconXo-mate hat folgendes geschrieben:
die teststruktur sieht derzeit so aus, soll aber später natürlich (teils erheblich) erweitert werden:
Du solltest vorsichtiger mit deiner Wortwahl sein: Bei "Struktur" wird jeder .Net-Programmierer natürlich an "struct" denken. Und nur die (und auch nicht alle von ihnen) sind, wie es die Marshal-Fehlermeldung schon sagt, direkt in ein Byte-Array kopierbar.
Allerdings hast du ja schon zum richtigen Werkzeug für Klassen gegriffen: der BinaryFormatter. Du musst nur deinen Code etwas umstellen, denn die Größe wirst du im Voraus nicht bestimmen können:

C#-Quelltext
1:
2:
3:
4:
using (var stream = new MemoryStream()) {
  binFormatter.Serialize(outputStream, msc);
  return stream.ToArray();
}


Xo-mate - Mi 26.03.08 13:09

yeah, super! Danke!

Zur Vervollständigung lautet der Code nun:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
        private byte[] convertField(testclass toCheck)
        {
            testclass msc = toCheck;
            BinaryFormatter binFormatter = new BinaryFormatter();            

            using (MemoryStream stream = new MemoryStream())
            {
                binFormatter.Serialize(stream, msc);
                return stream.ToArray();
            }
        }


Christian S. - Mi 26.03.08 13:53

msc ist doch eigentlich überflüssig, oder? Da Klassen Referenzdatentypen sind, arbeitest Du weiterhin mit derselben Instanz.


Xo-mate - Fr 28.03.08 16:01

jopp, haste recht ;)
Hab ich bei mir im Code auch schon so stehen.