Qt + protobuf, типы? - PullRequest
       10

Qt + protobuf, типы?

14 голосов
/ 23 ноября 2010

Я бы хотел окунуться в буферы протокола Google при разработке Qt, но у меня возникли проблемы с выяснением, как их лучше всего включить.

В конечном итоге я хочу отправить с QUdpSocket и QTcpSocket, используябуферы протокола.

Каков наилучший способ перехода от буфера протокола message к отправке данных через сокет (QByteArray) и затем обратно на другую сторону?

Ответы [ 4 ]

12 голосов
/ 23 ноября 2010

Создание QByteArray из объекта protobuf:

Person person; // a protobuf object
person.set_id(123);
person.set_name("Bob");
person.set_email("bob@example.com");

std::ostringstream out;
person.SerializeToOstream(&out);
QByteArray byteArray(out.str().c_str());
sendSerializedPersonOverQTcpSocket(byteArray);

Считывание объекта protobuf из QByteArray:

QByteArray byteArray = readSerializedPersonFromQTcpSocket();
Person person;
if (!person.ParseFromArray(byteArray, byteArray.size())) {
  std::cerr << "Failed to parse person.pb." << std::endl;
}
6 голосов
/ 29 июля 2011

Вместо:

std::ostringstream out;
person.SerializeToOstream(&out);
QByteArray byteArray(out.str().c_str());

вы также можете написать:

QByteArray byteArray(person.SerializeAsString().c_str());

РЕДАКТИРОВАТЬ: выше двух дает тот же результат, но я не уверен, что это правильно.Кажется, что этот работает лучше:

QByteArray byteArray(QString::fromStdString(person.SerializeAsString()));

EDIT2: ОК, теперь я знаю, как это работает: первые два способа неверны, если в сериализации есть \ 0 char - все, что после этого, затем теряется.Чтобы исправить это можно написать:

QByteArray byteArray(person.SerializeAsString().c_str(), person.ByteSize());
4 голосов
/ 24 июля 2016

Использование приведенного ниже кода действительно опасно

std::ostringstream out;
person.SerializeToOstream(&out);
QByteArray byteArray(out.str().c_str());
sendSerializedPersonOverQTcpSocket(byteArray);

Хорошее объяснение вы можете найти здесь В protobuf-c может ли необязательная переменная uint32 иметь значение 0

Правильный способ создания QByteArray из сообщения protobuf -

QByteArray byteArray;
byteArray.resize(message.ByteSize());
message.SerializeToArray(byteArray.data(), byteArray.size());
3 голосов
/ 10 февраля 2011

@ Джеймс: Вы можете использовать ParseFromArray(), например, как показано ниже: (Обратите внимание, что ParseFromArray() доступно только в версиях lib для proto-buf-lite).

void convertQByteArrayToUser(QByteArray& aByteArray)
{
    com::your::name_space::User user;
    if(!user.ParseFromArray(aByteArray.data(), aByteArray.size())) 
    {
        //could not parse
    }
    else { //yayyyyy            
        if(user.has_userid())
        {
            //...
        }
    }
}
...