Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

31

29.07.2014, 15:45

Doch, das interessiert sie, deswgeen muss das mit Extensible gemacht werden.

Fehlermeldung im Anhang.

Die .proto Files sind ja so aufgebaut und aus denen habe ich mit protogen die .cs Files (für protobuf) generiert:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
File - Messageheader.proto:
message MessageHeader{
required int32 Id = 1;
}

File - MainMessage.proto:
import "Messageheader.proto";

message MainMessage{
required MessageHeader Header = 1;
extensions 100 to 199;
}



File - MessageBool.proto:
import "Messageheader.proto";
import "MainMessage.proto";

message MessageBool{
required bool Successfull = 1;
optional string Information = 2;
    extend MainMessage{
        optional MessageBool Bool = 100;
    }
}

File - MessageLogin.proto:
import "Messageheader.proto";
import "MainMessage.proto";

message MessageLogin{
required string Username = 1;
required string Password = 2;
    extend MainMessage{
        optional MessageLogin Login = 101;
    }
}


Zu sehen ist, dass MainMessage (Ausser für MessageHeader) nur extensions bereit stellt. Mit C++ gibt das Erstellen solcher Nachrichten (zumindest bisher) keinerlei Probleme. Da Protobuf-net aber leicht anders funktioniert, schaffe ich es aber irgendwie nicht richtig diese MainMessage zu erstellen. Im Debugger scheint die MainMessage im C# Programm vor der Serialisierung noch die extension zu haben, aber lese ich den serialisierten string im C++ Programm ein, dann fehlt die extension. Ausserdem sieht der String sehr komisch aus... Möglicherweise muss eine Message mit extension anders serialisiert werden. Aber ich komme mit absolut keinem meiner Lösungsansätze näher ans Ziel und im Internet finde ich auch nichts.

Probiert habe ich auch schon Protobuf c-sharp port zu benutzen, aber dort gibt es absolut gar nichts zu Messages mit extensions.

Das hat doch bestimmt schon mal jemand von euch gemacht, wie habt ihr das gelöst?


EDIT: Wegen Blue Cobolds seinem PS:

Ja, weil diese überholt war. Wie von Marc Gravell vorgeschlagen, habe ich die Protofiles nun per Protogen erzeugt. Es stand zur Debatte, ob C++ deswegen nicht auslesen konnte. Das Problem mit dem komisch langen String und generell eigentlich alle Probleme bleiben trotzdem :D
»ERROR« hat folgendes Bild angehängt:
  • Unbenannt.png

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »ERROR« (29.07.2014, 15:53)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

32

29.07.2014, 15:53

Wie ich schon sagte, ich bezog mich auf die C#-Klassen-Definition, die Du wieder gelöscht hast. Daher kann ich jetzt schlecht raten, wie der aktuelle C# Code dazu aussieht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

33

29.07.2014, 15:56

Ich weiss nicht wie ich es sonst zeigen soll, deswegen einfach mal so:

Das sind die von Protogen generierten .cs files:

MainMessage.cs

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace PA_Client_CS
{
  [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"MainMessage")]
  public partial class MainMessage : global::ProtoBuf.IExtensible
  {
    public MainMessage() {}
    
    private MessageHeader _Header;
    [global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"Header", DataFormat = global::ProtoBuf.DataFormat.Default)]
    public MessageHeader Header
    {
      get { return _Header; }
      set { _Header = value; }
    }
    private global::ProtoBuf.IExtension extensionObject;
    global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
      { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
  }
  
}


MessageLogin.cs:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
namespace PA_Client_CS
{
  [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"MessageLogin")]
  public partial class MessageLogin : global::ProtoBuf.IExtensible
  {
    public MessageLogin() {}
    
    private string _Username;
    [global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"Username", DataFormat = global::ProtoBuf.DataFormat.Default)]
    public string Username
    {
      get { return _Username; }
      set { _Username = value; }
    }
    private string _Password;
    [global::ProtoBuf.ProtoMember(2, IsRequired = true, Name=@"Password", DataFormat = global::ProtoBuf.DataFormat.Default)]
    public string Password
    {
      get { return _Password; }
      set { _Password = value; }
    }
    private global::ProtoBuf.IExtension extensionObject;
    global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
      { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
  }
  
}

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

34

29.07.2014, 15:57

Das is natürlich was ganz anderes als das, was Du zuerst auf Stackoverflow hattest.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

35

29.07.2014, 15:58

Das stimmt :D Das auf Stackoverflow waren erste Versuche, wie es angeblich klappen soll, tat es aber nicht. Deswegen habe ich es ja schon länger zurück gezogen und das aktuelle (Gegenrierung der Protogen) gepostet ;)

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

36

29.07.2014, 16:00

So und dein aktueller Code zur Serialisierung und Deserialisierung sieht nun wie aus? Hoffentlich nicht mehr als String, denn das spuckt Dir offenbar ja viel mehr Bytes aus (weil der Buffer intern größer ist) als Du eigentlich haben willst. Die ToArray-Methode ist eher das, was Du dort willst. Und Strings willst Du dort gar keine.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

37

29.07.2014, 23:37

So, alles etwas umgebaut, so dass jetzt nur noch byte arrays verwendet werden.

Also der Fehler liegt definitv beim Serialize. Erzeuge ich die gleiche MainMessage in C++ ist sie 24 Byte(unsigned char) gross, in C# nur 11 Bytes. In der C# Nachricht fehlt nach dem Serialize die extensions(MessageLogin).

Das ist der Code zur Serialisierung:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
       public static byte[] Serialize(object protobufMessage)
        {
            byte[] bytes;
            using (MemoryStream stream = new MemoryStream())
            {
                Serializer.Serialize(stream, protobufMessage);
                bytes = stream.ToArray();
            }
         return bytes;
         }
          



Hier wird die MainMessage erzeugt und Serialize aufgerufen:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
            MainMessage message = new MainMessage
            {
                Header = new MessageHeader
                {
                    Id = 1,
                },

            };
            MessageLogin login = new MessageLogin
            {
                Username = "error",
                Password = "pw",
            };
            Extensible.AppendValue<MessageLogin>(message, 101, login);

            byte[] b = ProtoZmq.Serialize(login);


So ist eigentlich alles richtig, aber was muss ich tun, damit die extension dabei bleibt?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »ERROR« (30.07.2014, 10:19)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

38

30.07.2014, 06:37

byte[] b = ProtoZmq.Serialize(login);?
Sicher? Ich hätte ja was anderes erwartet. Was "ProtoZmq" ist, weiß ich allerdings ebenfalls nicht. Ich hätte hier mit Serializer gerechnet.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (30.07.2014, 06:43)


ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

39

30.07.2014, 10:16

ProtoZmq ist ne von mir erstellte Klasse, für die Serialiesung. Serialize ist die Methode, welche in dem oberen der beiden Codeschnipsel ist. Dort benutze ich ja Serializer. Da fehlt übrigens noch am Ende das return bytes;( ist jetzt rein editiert).

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

40

30.07.2014, 10:27

Nochmal die Frage: Bist Du Dir sicher?
byte[] b = ProtoZmq.Serialize(login);?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige