Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Bytes array to QByteArray.



  • It looks like this

    void UDP_Send(QByteArray data, QString remote_ip, quint16 remote_port)
    {
        QByteArray Data;
        
        uint8_t encrypted[CRYPT_SIZE];
        uint8_t *data_u8 = reinterpret_cast<uint8_t *>(data.data());
        
        CRYPTO_Encrypt(encrypted, CRYPT_SIZE, data_u8, MIN_CRYPT_SIZE);
        
        //Data.append(data);
        
        Data.append(QByteArray((encrypted, MIN_CRYPT_SIZE));  //error
        Data.append(QByteArray(static_cast<char*>(encrypted), MIN_CRYPT_SIZE)); //error
    
        udp_socket->writeDatagram(Data, QHostAddress(remote_ip), remote_port);
    }
    

    QByteArray(char* , size) - is the char type in Qt actually uint8_t? (so what is signed char?)



  • @jenya7
    Since QByteArray accepts const char *data for construction or directly for append(), simply cast your uint_t * to char *, or make it char * in the first place and do the cast to uint8_t * when you pass it to CRYPTO_Encrypt().



  • @JonB
    But uint8_t = 0..255 and char = -127..127. If I make encrypted as a char array I loose data. Do I miss something?



  • @jenya7
    Yes, you do "miss something"!

    Both uint8_t and char are a byte with 8 bits in it. The unsigned/signed are a matter of how something might interpret the byte/char, but they remain the same 8-bit pattern. No "data is lost" when you cast between them. Just trust me on this! :)

    When you cast you would be better using reinterpret_cast<>() than static_cast <>().



  • @JonB
    This way

    Data.append( QByteArray( static_cast<char*>(encrypted), MIN_CRYPT_SIZE ) );
    

    I get - static_cast from 'uint8_t *' (aka 'unsigned char *') to 'char *' is not allowed



  • @JonB said in Bytes array to QByteArray.:

    When you cast you would be better using reinterpret_cast<>() than static_cast <>().

    I see. Thank you. It works.


  • Moderators

    @jenya7 you would need reinterpret cast and an additional const_cast.

    You shouldn't be doing that anyway, use memcpy. More verbose to write, but more compiler robust, and probably just as fast.



  • @J-Hilk
    Like this?

    memcpy(Data.data(), encrypted, MIN_CRYPT_SIZE);
    

    I like it better.



  • @jenya7

    Data.append( reinterpret_cast<char*>(encrypted), MIN_CRYPT_SIZE );
    

    using QByteArray &QByteArray::append(const char *str, int len) is least typing.

    Or since you don't use the QByteArray Data; before this, and so don't need append(), you could just move the declaration to here:

    QByteArray Data( reinterpret_cast<char*>(encrypted), MIN_CRYPT_SIZE );
    


  • @jenya7 said in Bytes array to QByteArray.:

    memcpy(Data.data(), encrypted, MIN_CRYPT_SIZE);
    I like it better.

    What? Please don't go into using memcpy() when no need, this code does not append anything (you were appending), or does not set the size (will overflow unallocated memory) in the QByteArray (unless pre-sized).



  • @jenya7 said in Bytes array to QByteArray.:

     memcpy(Data.data(), encrypted, MIN_CRYPT_SIZE);
    

    I like it better.

    This is very dangerous!
    You have to ensure that buffer holden by Data is big enough to write the data (Data.size() >= MIN_CRYPT_SIZE) or you will corrupt memory!

    EDIT
    My suggestion for your code is:

    void UDP_Send(QByteArray data, QString remote_ip, quint16 remote_port)
    {
        QByteArray encrypted(CRYPT_SIZE, 0);
        
        CRYPTO_Encrypt(reinterpret_cast<uint8_t *>(encrypted.data()), 
                       encrypted.size(), 
                       reinterpret_cast<uint8_t *>(data.data()),
                       data.size());
        
        udp_socket->writeDatagram(encrypted, QHostAddress(remote_ip), remote_port);
    }
    


  • @KroMignon
    I see. Thank you.
    I thought about

    Data.resize(CRYPT_SIZE);
    

    But this way it's less coding.



  • @JonB said in Bytes array to QByteArray.:

    @jenya7
    Yes, you do "miss something"!

    Both uint8_t and char are a byte with 8 bits in it. The unsigned/signed are a matter of how something might interpret the byte/char, but they remain the same 8-bit pattern. No "data is lost" when you cast between them. Just trust me on this! :)

    When you cast you would be better using reinterpret_cast<>() than static_cast <>().

    Following the logic.
    Slave sends (not Qt, embedded code)

    float fval = SensorGetValue();
    
    ival = (int)fval;
                
    udp_tx_buffer[5] = ival;
    udp_tx_buffer[6] = ival >> 8;
    udp_tx_buffer[7] = ival >> 16;
    udp_tx_buffer[8] = ival >> 24;  
    

    On Qt side I get

    float fval  = static_cast<float>( (sens_msg->data[3] << 24) | (sens_msg->data[2] << 16) | (sens_msg->data[1]<< 8) | sens_msg->data[0]);
    

    But I get it truncated to integer.



  • @jenya7 said in Bytes array to QByteArray.:

    On Qt side I get
    float fval = static_cast<float>( (sens_msg->data[3] << 24) | (sens_msg->data[2] << 16) | (sens_msg->data[1]<< 8) | sens_msg->data[0]);

    But I get it truncated to integer.

    This totally wrong, sens_msg->data[] is a 8 bit value, so shifting it to left with 8 bit (or more) will fill it with '0'.
    You could cast each byte to an integer (before shifting) or use QDataStream:

    QDataStream stream(&sens_msg, QIODevice::ReadOnly);
    
    float fval;
    stream >> fval;
    

    cf. documentation https://doc.qt.io/qt-5/qdatastream.html.



  • @jenya7
    If your sender & receiver are on same architecture, so you don't care about any possible byte-ordering issues (I don't know whether they apply to float-types anyway), you could just send 4 bytes from &udp_tx_buffer[5] and receive as 4 bytes into &fval. No individual bytes.



  • OK, I'll try it.


Log in to reply