QDataStream with wchar_t array
-
Hi,
I'm working on some IPC functionality, whereby a structure (defined within both applications) is sent from one application to another.
The source of the data is a memory-mapped file within Windows, which is accessed using the various Windows APIs. I won't dwell on that as I've verified that this is working as expected, and it doesn't have any relevance to my question/issue.
The structure looks like this:
struct myStruct { uint8_t val1; uint16_t val2; wchar_t val3[15]; wchar_t val4[35]; int32_t val5; float val6[4]; };
An instance of the structure is populated by casting from the memory-mapped file:
myStruct *myStructInstance = (myStruct *)memoryMappedFile;
I'm using QDataStream (with a QByteArray) to serialise the structure for transmission to the remote application:
QByteArray ba; QDataStream ds(&ba, QIODevice::WriteOnly); ds.setVersion(QDataStream::Qt_5_15); ds << val1 << val2 << val3 << val4 << val5 << val6;
The packed QByteArray is then transmitted to the remote application (in this instance, via a QTcpSocket):
m_remoteClientSocket->write(ba); m_remoteClientSocket->flush();
My questions are as follows:
- Is this the advised method of sending a known structure between two applications?
- How do I then de-serialise the received QByteArray at the remote application? I understand how to do it for uint8_t, uint16_t, etc. types, but I'm not sure how to do it for arrays, particularly wchar_t arrays.
Any guidance would be greatly appreciated!
-
@jars121 said in QDataStream with wchar_t array:
ds << val1 << val2 << val3 << val4 << val5 << val6;
This does not do what you think it does because QDataStream has no overloads for c-arrays. You have to iterate over the arrays by yourself.
-
Hi,
In addition to what @Christian-Ehrlicher wrote, you should write the QDataStream operators for your structure. This will allow your code to be simpler.
-
Thank you both for your input, it's greatly appreciated.
I now understand the need for overloading the QDataStream operators. My next question is, what should the wchar_t be converted to to package it into the QDataStream? I.e. do I use a QString overload like this:
QDataStream &operator << (QDataStream &ds, const QString &val) { ds << (const char *) val.toLocal8Bit(); return ds; }
Which is called like this:
ds << val1 << val2 << QString("%1").arg(QString::fromWCharArray(myStructInstance->val3), (sizeof(myStructInstance->val3) / sizeof(wchar_t)), QChar(' ')) << etc.
The above allows me to fix the width of the resultant char array, so the data can be successfully unpacked by the remote application. I don't see why this wouldn't work, but I'm not sure whether this is the best way to deal with the wchar_t arrays.
EDIT: I've just realised that the size of the string is automatically packaged with the string, so the above 'fixed-width string conversion' isn't necessary. I've just tested the below, and am able to receive the receive the resultant data into a QByteArray and then convert it back into a QString in the remote application:
ds << val1 << val2 << QString::fromWCharArray(myStructInstance->val3) << etc.
-
This only works when your wchar_t doesn't contain '\0'.
Also it will ont work for val6