Problem with a data from UDP
-
I get some data
socket->readDatagram(udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);but the first argument is a char.
qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *host = nullptr, quint16 *port = nullptr);and I get bytes (uint8_t) - so my data will be trancated?
-
No, it won't. The first argument is a pointer which may point to a string of arbitrary length.
But better just use
receiveDatagram()https://doc.qt.io/qt-5/qudpsocket.html#receiveDatagram, with that function you can easily read the result as aQByteArray. -
I get some data
socket->readDatagram(udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);but the first argument is a char.
qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *host = nullptr, quint16 *port = nullptr);and I get bytes (uint8_t) - so my data will be trancated?
@jenya7 said in Problem with a data from UDP:
but the first argument is a char.
It isn't. It's a
char *.and I get bytes (uint8_t)
That will be:
typedef unsigned char uint8_t;.Size is OK. There will be no "truncation". What type does your
udp_buffer.data()return anyway? -
It's
QByteArray udp_buffer;Now I pass it to a parse function
uint32_t MSGPARSER::ParseMessage(QByteArray data, MESSAGE * sens_msg) { if (data[0] == INTERFACE_ID_NONE || data[1] > INTERFACE_ID_RS485) // error: use of erloaded operator '==' is ambiguous (with operand types 'QByteRef' and 'int') return MSG_PARSE_ERROR_WRONG_INTFACE_ID; else sens_msg->interface_id = data[0]; // warning: implicit conversion changes signedness: 'char' to 'uint8_t' (aka 'unsigned char') return 0; }So data[0] is a char.
-
It's
QByteArray udp_buffer;Now I pass it to a parse function
uint32_t MSGPARSER::ParseMessage(QByteArray data, MESSAGE * sens_msg) { if (data[0] == INTERFACE_ID_NONE || data[1] > INTERFACE_ID_RS485) // error: use of erloaded operator '==' is ambiguous (with operand types 'QByteRef' and 'int') return MSG_PARSE_ERROR_WRONG_INTFACE_ID; else sens_msg->interface_id = data[0]; // warning: implicit conversion changes signedness: 'char' to 'uint8_t' (aka 'unsigned char') return 0; }So data[0] is a char.
@jenya7 said in Problem with a data from UDP:
So data[0] is a char.
It's just a collection of 8 bits. UDP makes no assumptions about the data it is transporting. You can cast it to proper type if you know what it is.
-
@jenya7 said in Problem with a data from UDP:
So data[0] is a char.
It's just a collection of 8 bits. UDP makes no assumptions about the data it is transporting. You can cast it to proper type if you know what it is.
@sierdzio
So every time I have to cast?if ( static_cast<uint8_t>(data[0]) == INTERFACE_ID_NONE || static_cast<uint8_t>(data[0]) > INTERFACE_ID_RS485) return MSG_PARSE_ERROR_WRONG_INTFACE_ID; else sens_msg->interface_id = static_cast<uint8_t>(data[0]);It's not convenient at all. I have hundred bytes to parse. The first development environment I see that points char* to a network buffer.
socket->readDatagram( (uint8_t *) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')
It should be (void *) in the function prototype.
-
@sierdzio
So every time I have to cast?if ( static_cast<uint8_t>(data[0]) == INTERFACE_ID_NONE || static_cast<uint8_t>(data[0]) > INTERFACE_ID_RS485) return MSG_PARSE_ERROR_WRONG_INTFACE_ID; else sens_msg->interface_id = static_cast<uint8_t>(data[0]);It's not convenient at all. I have hundred bytes to parse. The first development environment I see that points char* to a network buffer.
socket->readDatagram( (uint8_t *) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')
It should be (void *) in the function prototype.
@jenya7
QByteArrayholdschars.uint8_tisunsigned char. If you compare them directly you are liable to get "unsigned/signed comparison" warnings. As you have seen.If you don't like having to explicitly do casting each time, you could, say, write your own utility function for "the i'th element of a
QByteArrayasunsigned char/uint_t", or the whole data asuint_t *.Separately, your parameter in
ParseMessage(QByteArray datawould be better declared asconst QByteArray &data. But that won't change the casting issue. -
@jenya7
QByteArrayholdschars.uint8_tisunsigned char. If you compare them directly you are liable to get "unsigned/signed comparison" warnings. As you have seen.If you don't like having to explicitly do casting each time, you could, say, write your own utility function for "the i'th element of a
QByteArrayasunsigned char/uint_t", or the whole data asuint_t *.Separately, your parameter in
ParseMessage(QByteArray datawould be better declared asconst QByteArray &data. But that won't change the casting issue. -
@JonB
socket->readDatagram( (uint8_t * ) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')
@jenya7 said in Problem with a data from UDP:
socket->readDatagram( *(uint8_t ) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);
This should be:
socket->readDatagram( (uint8_t *) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);EDIT:
socket->readDatagram( udp_buffer.data(), udp_buffer.size(), &sender, &senderPort); -
@jenya7 said in Problem with a data from UDP:
socket->readDatagram( *(uint8_t ) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);
This should be:
socket->readDatagram( (uint8_t *) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);EDIT:
socket->readDatagram( udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);@KroMignon said in Problem with a data from UDP:
@jenya7 said in Problem with a data from UDP:
socket->readDatagram( *(uint8_t ) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);
This should be:
socket->readDatagram( (uint8_t *) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);It is. The editor's problem
-
@KroMignon said in Problem with a data from UDP:
@jenya7 said in Problem with a data from UDP:
socket->readDatagram( *(uint8_t ) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);
This should be:
socket->readDatagram( (uint8_t *) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);It is. The editor's problem
-
@KroMignon said in Problem with a data from UDP:
@jenya7 said in Problem with a data from UDP:
socket->readDatagram( *(uint8_t ) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);
This should be:
socket->readDatagram( (uint8_t *) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);It is. The editor's problem
-
@KroMignon said in Problem with a data from UDP:
socket->readDatagram( udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);
This way I get array of chars I have to cast every byte.
socket->readDatagram((uint8_t *)udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);This way - error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')
-
You can use QDataStream to automatically convert all data to whatever format you require. To get a suitable device for it, use QBuffer.
-
@KroMignon said in Problem with a data from UDP:
socket->readDatagram( udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);
This way I get array of chars I have to cast every byte.
socket->readDatagram((uint8_t *)udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);This way - error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')
-
@KroMignon said in Problem with a data from UDP:
socket->readDatagram( udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);
This way I get array of chars I have to cast every byte.
socket->readDatagram((uint8_t *)udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);This way - error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')
@jenya7 said in Problem with a data from UDP:
his way - error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')
What are you doing?
socketis as instance ofQUdpSocketandudp_bufferan instance ofQByteArrayor not?This must work, as I always do it!
QByteArray datagram(socket->pendingDatagramSize(), 0); QHostAddress sender; quint16 senderPort; socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); -
@jenya7 said in Problem with a data from UDP:
his way - error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')
What are you doing?
socketis as instance ofQUdpSocketandudp_bufferan instance ofQByteArrayor not?This must work, as I always do it!
QByteArray datagram(socket->pendingDatagramSize(), 0); QHostAddress sender; quint16 senderPort; socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); -
What are you doing?
socket is as instance of QUdpSocket and udp_buffer an instance of QByteArray or not?Yes it is.
But taking char by char form datagram.data()
I have to cast - uint8_t b0 = static_cast<uint8_t>(datagram[0]);@jenya7 said in Problem with a data from UDP:
Yes it is.
But taking char by char form datagram.data()
I have to cast - byte b0 = static_cast<uint8_t>(datagram[0]);No:
for(const auto b : datagram) { qDebug() << "Byte value:" << quint8(b); }EDIT
oruint8_t* myPoint = static_cast<uint8_t*>(datagram.data()); -
What are you doing?
socket is as instance of QUdpSocket and udp_buffer an instance of QByteArray or not?Yes it is.
But taking char by char form datagram.data()
I have to cast - uint8_t b0 = static_cast<uint8_t>(datagram[0]);@jenya7
I will contribute one more time. I already told you what to do if you want to reduce repeated casting:If you don't like having to explicitly do casting each time, you could, say, write your own utility function for "the i'th element of a QByteArray as unsigned char/uint_t", or the whole data as uint_t *.
Same applies anywhere else.
For the record: I believe there have been discussions over the years about how some people would have preferred
QByteArrayto holdunsigned chars instead ofchars. It stays withchars due (at least partly) to it's (slightly weird) determination to end the data with\0and allow it to interchange fairly free withQString. This is not convenient for your case, but it is what it is, so you're going to have to work with it. -
@jenya7
I will contribute one more time. I already told you what to do if you want to reduce repeated casting:If you don't like having to explicitly do casting each time, you could, say, write your own utility function for "the i'th element of a QByteArray as unsigned char/uint_t", or the whole data as uint_t *.
Same applies anywhere else.
For the record: I believe there have been discussions over the years about how some people would have preferred
QByteArrayto holdunsigned chars instead ofchars. It stays withchars due (at least partly) to it's (slightly weird) determination to end the data with\0and allow it to interchange fairly free withQString. This is not convenient for your case, but it is what it is, so you're going to have to work with it.@JonB said in Problem with a data from UDP:
@jenya7
I will contribute one more time. I already told you what to do if you want to reduce repeated casting:If you don't like having to explicitly do casting each time, you could, say, write your own utility function for "the i'th element of a QByteArray as unsigned char/uint_t", or the whole data as uint_t *.
Same applies anywhere else.
To cast each element in a loop? It makes even worse, waste of run time.