1

I'm using protobuf to send/receive binary data from Cpp to Js and vice-versa and I'm using QWebChannel to communicate with the HTML client.

Question: How to deserialize binary data in cpp which is serialized and sent from Js?

Following I tried:

//Serialization: Cpp to JS - WORKING
tutorial::PhoneNumber* ph = new tutorial::PhoneNumber();
ph->set_number("555-515-135");
ph->set_type(500);

QByteArray  bytes = QByteArray::fromStdString(ph->SerializeAsString());
QString args = "\"" + bytes.toBase64(QByteArray::Base64Encoding) + "\"";

QString JsFunctionCall = QString("DeserializePhoneNumber(%1);").arg(args);
m_pWebView->page()->runJavaScript(JsFunctionCall);

 //Deserialization In JS - Js Code - WORKING
 var obj = phone_msg.PhoneNumber.deserializeBinary(data);
 console.log("PhoneNumber: " + obj.getNumber());
 console.log("Type: " + obj.getType());

 //Serialization in Js - WORKING
 var phNum = new phone_msg.PhoneNumber;
 phNum.setNumber("555-515-135");
 phNum.setId(500);

 var base64Str = btoa(phNum.serializeBinary());
 console.log("base64Str: " + base64Str);

 //Call Cpp function from Js
  MainChannel.SendMsgToCpp(base64Str);

Deserialization in Cpp - NOT WORKING

bool WebRelay::ReceiveMsgFromJs(QVariant data)
{
     QString str = data.toString();
     QByteArray bytedata = str.toLatin1(); 
     QByteArray base64data = QByteArray::fromBase64(bytedata); 
     std::string stdstr = base64data.toStdString();
     
     tutorial::PhoneNumber cppPhNum;
     //THIS IS NOT WORKING. Text and id are invalid
     cppPhNum.ParseFromArray(base64data.constData(), base64data.size());
     qDebug() << "Text:" << itemData.number();
     qDebug() << "id:" << cppPhNum.id();
}

Akshay R
  • 47
  • 6
  • "not working" is impossible to debug. Did you verify that you received the base64 data intact? Did you verify that the base64 decoding produces the same binary? – Botje Aug 12 '21 at 07:12
  • yes, base64 data is received correctly. verified. – Akshay R Aug 12 '21 at 09:17
  • Try using the `fromBase64` overload with the `QByteArray::AbortOnBase64DecodingErrors` flag set. – Botje Aug 12 '21 at 09:23
  • Not working. any example which shows deserialization in c++ coming from Js. Could not find what mistake I'm doing. I tried ParsefromArray and ParseFromString. not working – Akshay R Aug 12 '21 at 11:31

1 Answers1

2

Found the problem. I was getting comma-separated bytes from Js like: 10,7,74,115,73,116,101,109,49,16,45

I split the strings by ',' and created a QByteArray

QStringList strList = str.split(',');
QByteArray bytedata;
foreach(const QString & str, strList)
{
    bytedata+= (str.toUInt());
}
std::string stdstr = bytedata.toStdString();
itemData.ParseFromString(stdstr);

It works.

Also in JS, I removed convertion of the binary string to base64:

var base64Str = phNum.serializeBinary();
Akshay R
  • 47
  • 6