2012-02-06 7 views
17

Tôi muốn tuần tự hóa bộ đệm giao thức của mình thành một char *. Điều này có thể không? Tôi biết một người có thể sắp xếp theo thứ tự để nộp theo:C++ Bộ đệm giao thức của Google: serialize thành 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; 
} 

Nhưng tôi muốn tuần tự hóa thành kiểu chữ C * để truyền qua mạng.

Cách thực hiện việc này? Xin lưu ý rằng tôi rất mới với C++.

Trả lời

34

Đó là dễ dàng:

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

Kiểm tra documentation of MessageLite class cũng có, đó là lớp cha của tin nhắn và nó chứa các phương pháp hữu ích.

+0

Làm cách nào để truy cập chức năng SerializeToArray này? Cảm ơn, – Eamorr

+1

int size = address_book.By teSize(); void * buffer = malloc (kích thước); address_book.SerializeToArray (bộ đệm, kích thước); –

+0

Hi Evgen, có SerializeToArray bị phản đối hay gì đó? Tôi đang sử dụng phiên bản mới nhất của bộ đệm giao thức – Eamorr

9

Bạn có thể chuyển đổi kết quả đầu ra thành ostringstream và sử dụng stream.str() để nhận chuỗi và sau đó truy cập chuỗi c bằng string.c_str().

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

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

Đừng quên bao gồm sstream cho std::ostringstream.

+0

Chú thích! Cảm ơn bạn rất nhiều vì đã cung cấp mã. – Eamorr

+3

Một điều nữa - Tôi không có sẵn chức năng SerializeToOstream - chỉ cần một SerializeWithCachedSizes (...) và SerializeWithCachedSizesToArray (...); ( – Eamorr

+3

Theo tài liệu protobuf của Google, định dạng protobuf là nhị phân, và do đó có thể chứa null Tôi đã chạy qua các trường hợp gọi c_str() trên đầu ra của các kết quả tuần tự Protobuf trong một chuỗi C bị cắt ngắn, vì các byte rỗng được ghi vào bộ đệm được cung cấp, và sử dụng thêm bộ đệm đó với các hàm C-style bình thường. Tôi sẽ không khuyên bạn nên sử dụng phương pháp này ở tất cả - thẳng thắn, tôi không tin rằng nó bao giờ an toàn để serialize protobufs đến các chuỗi kiểu C, và đó có thể là lý do tại sao Google không cung cấp tùy chọn này –

3

Bạn có thể sử dụng ByteSize để nhận số byte tin nhắn sẽ chiếm và sau đó SerializeToArray để điền một mảng với thông báo được mã hóa.

0

Vẫn còn một dòng mã nữa để xử lý dữ liệu được tuần tự hóa có thể chứa số không.

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