Протокол Buffer # 3 отправляет сообщение с c ++ на c # - PullRequest
0 голосов
/ 10 мая 2018

Я пытаюсь отправить несколько простых сообщений с c ++ на c # и наоборот, но мне чего-то не хватает ...

c ++ код для сериализации образца сообщения:

std::string data;

SampleHello hello;
hello.set_name("Hello");
hello.Set_num(12);
hello.SerializeToString(&data);

C # получить

SampleHello.Parser.ParseFrom(buffer)

А я получаю

Google.Protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero).

Я не знаю, кажется ли мне, что я что-то упустил полностью, это кажется таким простым и все же ... во всяком случае, я пробовал несколько других решений безрезультатно, например, использование решения из C # Google.ProtocolBuffers Метод десериализации (proto3 )

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

После многих потраченных впустую времени из-за того, что не очень хорошо знал c ++, и после того, как занялся различными решениями, такими как gRPC ... Я наконец нашел рабочее решение.

Проблема была в стороне c ++, где некоторые символы были добавлены, когда я пытался отправить message.c_str () напрямую через сокет.

рабочее решение для отправки простого сообщения protobuf на c ++:

std::string data;

SampleHello hello;
hello.set_name("Hello");
hello.set_num(12); 
hello.SerializeToString(&data);

char messageToBeSent[data.length()];

sprintf(messageToBeSent, "%s", data);

//simply sends via the socket using write(mSocket, msgToBeSent, msgSize);
session->send(messageToBeSent,sizeof(messageToBeSent));

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

#include "google/protobuf/io/zero_copy_stream_impl_lite.h"

typedef google::protobuf::io::ArrayInputStream arrayIStream;

void HandlePacket(int packetSize)
{
   char* packet = newchar[packetSize];  //allocate some space for the message
   rcvBuffer.Read(packet,packetSize); //the buffer where our received messages are
   arrayIStream arr(rcvBuffer.GetBuffer(), packetSize);   //pass the received message to a zero coded input object so we can use the delimited functions

   HeaderProto header;    //the header as described in the .proto file
   if (readDelimitedFrom(&arr,&header)) //readDelimitedFrom is the c++ solution as provided from the author of the c++ lib (look below for link)
   {
      //Do stuff with your message
   }
   delete packet;
}

readDelimitedFrom решения

0 голосов
/ 10 мая 2018

0A 0C 48 65 6C 6C 6F 20

Да, в этих данных что-то не так;0A означает «поле 1, длина префикса»;0C означает 12 байтов ... и у вас есть только еще 6 байтов данных;следующие 5 "Hello";так как мы все еще пропускаем 7 байтов из поля 1, 20 может быть пробелом, который мог бы иметь смысл, если бы это было на самом деле "Hello world!"?И мы даже не коснулись num / 12, для которого потребуются еще несколько байтов.

Полагаю, вы не выделили достаточно большой буфер.Я предполагаю, что где-то рядом с SerializeToString есть API, чтобы сообщить вам, сколько байтов нужно для буфера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...