C # — Есть ли способ десериализовать структуру, сериализованную в C Boost ASIO?

#c# #c #boost-asio

#c# #c #boost-asio

Вопрос:

Я использую Boost ASIO в качестве сетевого решения TCP-сервера.

Вот как я сериализуюструктуру в C :

 struct AccountRole {
    int id;
    std::string name;

    template <typename Archive>
    void serialize(Archiveamp; ar, const unsigned int version)
    {
        ar amp; id;
        ar amp; name;
    }
};

boost::asio::connect(s, resolver.resolve( defaultIP,config.GetConfigValue("AuthServerPort", defaultPort)));

size_t const header_length = 8;
size_t const body_size_b = 8;
std::string data;


ServerOpcode opc;
opc = ServerOpcode::SMSG_LOGIN_REQUEST_RESPONSE_TEST;

Vibranium::AccountRole ac;
ac.id = 5;
ac.name = "John Snow";

std::string message;

std::ostringstream struct_stream;
boost::archive::text_oarchive archive(struct_stream);
archive << ac;
message = struct_stream.str();
message.resize(message.length());
  

И вот как я его отправил:

 std::ostringstream header_stream;
header_stream << std::setw(header_length) << std::hex << opc;

std::ostringstream body_size_stream;
body_size_stream << std::setw(body_size_b) << std::hex << message.length();

data  = header_stream.str();
data  = body_size_stream.str();
data  =  message;
size_t request_length = data.length();


boost::asio::write(s, boost::asio::buffer(data,request_length));
  

Если бы это был C , я собираюсь десериализовать структуру следующим образом:

    Vibranium::AccountRole ac;

   try
   {
       std::string archive_data(amp;_packet.body_[0], _packet.body_in_bytes);
       std::istringstream archive_stream(archive_data);
       boost::archive::text_iarchive archive(archive_stream);
       archive >> ac;
   }
   catch (std::exceptionamp; e)
   {
       std::cout << "Error bace!" << std::endl;
       // Unable to decode data.
       boost::system::error_code error(boost::asio::error::invalid_argument);
       return;
   }
  

Однако C # не поддерживает Boost Asio и archive .

Итак, мой вопрос в том, есть ли другой способ сериализации и десериализации структуры в C #, который совместим с Boost ASIO?

Обратите внимание, что C # будет использоваться для клиента, а C — в качестве серверного решения.

Комментарии:

1. Взгляните на класс BinaryReader в C #. Я смог сериализовать и десериализовать двоичные данные между C # и C . Другой альтернативой является использование gRPC

2. Как насчет типов в структурах, подобных std::string тому, которого нет в C# ? Хорошо ли это справляется с такими?

3. Строки болезненны в C . Вы должны знать, как она сериализуется. Скорее всего, это длина, за которой следует строка. Вы должны знать, какой тип используется для длины (byte, short, int или номер переменной ширины) и что такое string encoding.is используется. Скорее всего, кодировка будет ASCII с 1 символом на байт, но она также может быть широкоформатным. Найдите формат C и используйте BinaryReader, чтобы прочитать его на C #.

4. сериализация boost предназначена только для чтения с помощью сериализации boost, используйте кроссплатформенную сериализацию, такую как protobuf

5. Если вы не можете изменить сериализацию, вы могли бы рассмотреть возможность создания проекта c / cli и выполнить десериализацию в нем.