2012-02-06 658 views
17

Quiero serializar mi buffer de protocolo a un char *. es posible? Sé que se puede serializar a presentar según:C++ Buffers de Protocolo de Google: serialize to 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; 
} 

Pero me gustaría para serializar a un char * C-estilo para su transmisión a través de una red.

¿Cómo hacer esto? Tenga en cuenta que soy muy nuevo en C++.

Respuesta

34

Eso es fácil:

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

Comprobar documentation of MessageLite class Además, es la clase padre del mensaje y contiene métodos útiles.

+0

¿Cómo accedo a esta función SerializeToArray? Gracias, – Eamorr

+1

int size = address_book.By teSize(); void * buffer = malloc (tamaño); address_book.SerializeToArray (buffer, tamaño); –

+0

Hola Evgen, ¿ha quedado obsoleto SerializeToArray o algo así? Estoy usando la última versión de los buffers de protocolo – Eamorr

9

Puede filtrar la salida a ostringstream y usar stream.str() para obtener la cadena y luego acceder al string con string.c_str().

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

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

No se olvide de incluir sstream para std::ostringstream.

+0

You legend! Muchas gracias por proporcionar el código. – Eamorr

+3

Una cosa más: no tengo una función SerializeToOstream disponible, solo una SerializeWithCachedSizes (...) y SerializeWithCachedSizesToArray (...); ( – Eamorr

+3

De acuerdo con los documentos protobuf de Google, el formato protobuf es binario y, por lo tanto, podría contener nulo Me he encontrado con ocasiones donde llamar a c_str() en el resultado de la serialización de Protobuf resulta en una cadena C truncada, porque los bytes nulos se escriben en el búfer proporcionado, y el uso posterior de ese búfer con funciones normales de estilo C lo interpreta como terminar con un terminador nulo. No recomendaría usar este método en absoluto; francamente, no creo que sea seguro serializar protobufs en cadenas tipo C, y esa es probablemente la razón por la que Google no proporciona esta opción –

3

Puede usar ByteSize para obtener el número de bytes que ocupará el mensaje y luego SerializeToArray para llenar una matriz con el mensaje codificado.

0

Todavía hay una línea más de código para encargarse del hecho de que los datos serializados pueden contener cero.

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 
Cuestiones relacionadas