Как сериализовать в char * с использованием буферов протокола Google?

Я хочу упорядочить свой буфер протокола до char *. Это возможно? Я знаю, что можно сериализовать файл в соответствии с:

fstream output("/home/eamorr/test.bin", ios::out | ios::trunc | ios::binary);
if (!address_book.SerializeToOstream(&output)) {
  cerr << "Failed to write address book." << endl;
  return -1;
}

Но я хотел бы сериализовать для C-style char * для передачи по сети.

Как это сделать? Пожалуйста, имейте в виду, что я очень новичок в С++.

Ответы

Ответ 1

Это легко:

size_t size = address_book.ByteSizeLong(); 
void *buffer = malloc(size);
address_book.SerializeToArray(buffer, size);

Отметьте документацию класса MessageLite, это родительский класс Message и содержит полезные методы.

Ответ 2

Вы можете запрограммировать вывод на ostringstream и использовать stream.str(), чтобы получить строку, а затем получить доступ к c-строке с помощью string.c_str().

std::ostringstream stream;
address_book.SerializeToOstream(&stream);

string text = stream.str();
char* ctext = text.c_str();

Не забудьте включить sstream для std::ostringstream.

Ответ 3

Вы можете использовать ByteSizeLong(), чтобы получить количество байтов, которое займет сообщение, а затем SerializeToArray(), чтобы заполнить массив закодированным сообщением.

Ответ 4

Еще одна строка кода, чтобы позаботиться о том, что сериализованные данные могут содержать ноль.

std::ostringstream stream;
address_book.SerializeToOstream(&stream);

string text = stream.str();
char* ctext = text.c_str();    // ptr to serialized data buffer
//  strlen(ctext) would wrongly stop at the 1st 0 it encounters.
int   data_len = text.size();  // length of serialized data

Ответ 5

Решение с умным указателем на массив:

size_t size = address_book.ByteSizeLong();
std::unique_ptr<char[]> serialized(new char[size]);
address_book.SerializeToArray(&serialized[0], static_cast<int>(size));