Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QByteArray to LabVIEW Byte Array conversion
QtWS25 Last Chance

QByteArray to LabVIEW Byte Array conversion

Scheduled Pinned Locked Moved Unsolved General and Desktop
labviewconversionqbytearraybytearrayconst char
10 Posts 3 Posters 1.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • U Offline
    U Offline
    UvQtcYZJuD7J5VW7
    wrote on last edited by UvQtcYZJuD7J5VW7
    #1

    Hello,

    I have a main application in LabVIEW that retrieves Byte Array from a websocket. These Byte Array are sent to a DLL written with Qt to be deserialized (LV Byte Array -> QByteArray conversion). This DLL returns a string OR an Byte Array.

    Currently, I use const char*. This works well for strings but for Byte Array, the final 0 (which is a value for me and I want to get it) is not returned. It is considered as a \0.

    How could I do to implement these conversions properly ?

    Qt DLL decoder : (I give a Byte Array, I get a string)

    const char* myClass::decodeMsg(char* receivedMessageString, int32_t length)
    {
        QByteArray receivedMessage(receivedMessageString, length);
        QString response;
    
        // decoding and assign string to response
    
        return response.toUtf8().constData();
    }
    

    Qt DLL encoder : (I give string or numeric, I wan't get a Byte Array to send on my websocket)

    const char* myClass::LVSetPower(int8_t l)
    {
        // prepare my request as requete
        std::string serializedMessage = requete.SerializeAsString();
        QByteArray serializedArray = QByteArray(serializedMessage.c_str(), serializedMessage.length());
        return reinterpret_cast<const char*>(serializedArray.constData());
    }
    

    In LabVIEW, I put a CLFN (Call Library Function Node) and just I send and get CString pointer. I can't specify a minimal length because my serialization return me Byte Array with random length (it can be 8 bytes, 7 bytes, or 70 !)

    Thanks for your help.

    JonBJ JKSHJ 2 Replies Last reply
    0
    • U UvQtcYZJuD7J5VW7

      Hello,

      I have a main application in LabVIEW that retrieves Byte Array from a websocket. These Byte Array are sent to a DLL written with Qt to be deserialized (LV Byte Array -> QByteArray conversion). This DLL returns a string OR an Byte Array.

      Currently, I use const char*. This works well for strings but for Byte Array, the final 0 (which is a value for me and I want to get it) is not returned. It is considered as a \0.

      How could I do to implement these conversions properly ?

      Qt DLL decoder : (I give a Byte Array, I get a string)

      const char* myClass::decodeMsg(char* receivedMessageString, int32_t length)
      {
          QByteArray receivedMessage(receivedMessageString, length);
          QString response;
      
          // decoding and assign string to response
      
          return response.toUtf8().constData();
      }
      

      Qt DLL encoder : (I give string or numeric, I wan't get a Byte Array to send on my websocket)

      const char* myClass::LVSetPower(int8_t l)
      {
          // prepare my request as requete
          std::string serializedMessage = requete.SerializeAsString();
          QByteArray serializedArray = QByteArray(serializedMessage.c_str(), serializedMessage.length());
          return reinterpret_cast<const char*>(serializedArray.constData());
      }
      

      In LabVIEW, I put a CLFN (Call Library Function Node) and just I send and get CString pointer. I can't specify a minimal length because my serialization return me Byte Array with random length (it can be 8 bytes, 7 bytes, or 70 !)

      Thanks for your help.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @UvQtcYZJuD7J5VW7 said in QByteArray to LabVIEW Byte Array conversion:

      Currently, I use const char*. This works well for strings but for Byte Array, the final 0 (which is a value for me and I want to get it) is not returned. It is considered as a \0.

      I don't know what this means. Something being char * has no relevance/effect on whether it has or how it handles a \0 it might contain. That is a different matter from how e.g. strcpy() might handle a \0 it encounters, but that is nothing to do with it being char *.

      When you talk about "Byte Array" at various points in your question, how do we know which of LV Byte Array or QByteArray you mean? I don't know what the rules for a LabView Byte array might be.

      Qt QByteArrays have the unusual property of always having an extra \0 at the end of the data, no matter what the data contains. That extra byte is not including in the QByteArray's count/length, and is only there to make it a bit interoperable with QStrings. You can probably forget it's there and never worry about it.

      A CString is what? A Microsoft MFC class for handling strings? No idea about its representation or compatibility with whatever.

      Anyway, I'm sorry but I can't figure just what you asking/saying, where exactly what problem is. In a nutshell, always pass a length/count around with a byte array (QByteArray has that), any operations should respect that byte count and not care about any embedded \0. If you let it be treated as a string, functions are liable to stop processing it at any \0; but then if it is a string that's fair enough.

      BTW, great username for this forum, must be really easy to remember.

      1 Reply Last reply
      0
      • U UvQtcYZJuD7J5VW7

        Hello,

        I have a main application in LabVIEW that retrieves Byte Array from a websocket. These Byte Array are sent to a DLL written with Qt to be deserialized (LV Byte Array -> QByteArray conversion). This DLL returns a string OR an Byte Array.

        Currently, I use const char*. This works well for strings but for Byte Array, the final 0 (which is a value for me and I want to get it) is not returned. It is considered as a \0.

        How could I do to implement these conversions properly ?

        Qt DLL decoder : (I give a Byte Array, I get a string)

        const char* myClass::decodeMsg(char* receivedMessageString, int32_t length)
        {
            QByteArray receivedMessage(receivedMessageString, length);
            QString response;
        
            // decoding and assign string to response
        
            return response.toUtf8().constData();
        }
        

        Qt DLL encoder : (I give string or numeric, I wan't get a Byte Array to send on my websocket)

        const char* myClass::LVSetPower(int8_t l)
        {
            // prepare my request as requete
            std::string serializedMessage = requete.SerializeAsString();
            QByteArray serializedArray = QByteArray(serializedMessage.c_str(), serializedMessage.length());
            return reinterpret_cast<const char*>(serializedArray.constData());
        }
        

        In LabVIEW, I put a CLFN (Call Library Function Node) and just I send and get CString pointer. I can't specify a minimal length because my serialization return me Byte Array with random length (it can be 8 bytes, 7 bytes, or 70 !)

        Thanks for your help.

        JKSHJ Offline
        JKSHJ Offline
        JKSH
        Moderators
        wrote on last edited by
        #3

        @UvQtcYZJuD7J5VW7

        1. Do not return QByteArray::constData()!!! Your QByteArray gets destroyed at the end of your functions, so your returned pointer becomes a dangling pointer.
        2. If your data can contain '\0', then you cannot pass it as const char * ("C String Pointer" in LabVIEW). You must pass it as an LStrHandle instead ("String Handle" in LabVIEW).

        This means you must call LabVIEW Manager functions to pass data between C++ and LabVIEW: https://zone.ni.com/reference/en-XX/help/371361R-01/lvexcode/labview_manager_functions/

        See https://github.com/JKSH/LQ-Bindings/blob/master/src/Cpp/lqtypes.cpp -- I have written some functions that:

        • Resize an LStrHandle and copy a QByteArray's data into it
        • Convert an LStrHandle into a QByteArray
        • Convert an LStrHandle into a QString

        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

        U 1 Reply Last reply
        4
        • JKSHJ JKSH

          @UvQtcYZJuD7J5VW7

          1. Do not return QByteArray::constData()!!! Your QByteArray gets destroyed at the end of your functions, so your returned pointer becomes a dangling pointer.
          2. If your data can contain '\0', then you cannot pass it as const char * ("C String Pointer" in LabVIEW). You must pass it as an LStrHandle instead ("String Handle" in LabVIEW).

          This means you must call LabVIEW Manager functions to pass data between C++ and LabVIEW: https://zone.ni.com/reference/en-XX/help/371361R-01/lvexcode/labview_manager_functions/

          See https://github.com/JKSH/LQ-Bindings/blob/master/src/Cpp/lqtypes.cpp -- I have written some functions that:

          • Resize an LStrHandle and copy a QByteArray's data into it
          • Convert an LStrHandle into a QByteArray
          • Convert an LStrHandle into a QString
          U Offline
          U Offline
          UvQtcYZJuD7J5VW7
          wrote on last edited by
          #4

          @JKSH Wow ! You have given me a lot of leads for research. Thank you, I'll test it all and get back to you.

          1 Reply Last reply
          0
          • U Offline
            U Offline
            UvQtcYZJuD7J5VW7
            wrote on last edited by
            #5

            @JKSH said in QByteArray to LabVIEW Byte Array conversion:

            If your data can contain '\0', then you cannot pass it as const char * ("C String Pointer" in LabVIEW). You must pass it as an LStrHandle instead ("String Handle" in LabVIEW).

            In Call Library Function Node, we can't get LStrHandle in return type. We juste have CStr or Pascal String.
            What do you mean when you said You must pass it as an LStrHandle ?

            JKSHJ 1 Reply Last reply
            0
            • U UvQtcYZJuD7J5VW7

              @JKSH said in QByteArray to LabVIEW Byte Array conversion:

              If your data can contain '\0', then you cannot pass it as const char * ("C String Pointer" in LabVIEW). You must pass it as an LStrHandle instead ("String Handle" in LabVIEW).

              In Call Library Function Node, we can't get LStrHandle in return type. We juste have CStr or Pascal String.
              What do you mean when you said You must pass it as an LStrHandle ?

              JKSHJ Offline
              JKSHJ Offline
              JKSH
              Moderators
              wrote on last edited by JKSH
              #6

              @UvQtcYZJuD7J5VW7 said in QByteArray to LabVIEW Byte Array conversion:

              In Call Library Function Node, we can't get LStrHandle in return type. We juste have CStr or Pascal String.

              Use a function argument to pass the data from C++ to LabVIEW. Don't use the "real" return value. (Treat it like a non-const reference or a non-const pointer)

              What do you mean when you said You must pass it as an LStrHandle ?

              LabVIEW Call Library Function Node configuration

              Note: If you pass receiveMessageString as a String Handle instead of a C String Pointer, then you don't need the length argument.

              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

              U 1 Reply Last reply
              1
              • JKSHJ JKSH

                @UvQtcYZJuD7J5VW7 said in QByteArray to LabVIEW Byte Array conversion:

                In Call Library Function Node, we can't get LStrHandle in return type. We juste have CStr or Pascal String.

                Use a function argument to pass the data from C++ to LabVIEW. Don't use the "real" return value. (Treat it like a non-const reference or a non-const pointer)

                What do you mean when you said You must pass it as an LStrHandle ?

                LabVIEW Call Library Function Node configuration

                Note: If you pass receiveMessageString as a String Handle instead of a C String Pointer, then you don't need the length argument.

                U Offline
                U Offline
                UvQtcYZJuD7J5VW7
                wrote on last edited by
                #7

                @JKSH Great ! It works.

                Now, my data are well returned (copied) in LabVIEW but at the end of the execution, LabVIEW crashes with the following error code : DAbort 0xF50EFD7B in MemoryManager.cpp

                setPower function into Qt DLL :

                int myClass::setPower(char *receivedMessageString, char *responseMessageString, size_t *size)
                {
                    // Error codes
                    int noError = 0;
                    int buffToSmall = 10;
                
                    QByteArray receivedMessage(receivedMessageString, strlen(receivedMessageString));
                
                    std::string response(receivedMessage.constData(), receivedMessage.length());
                
                    if(*size <= response.length())
                    {
                        return buffToSmall;
                    }
                
                    qstrncpy(responseMessageString, response.c_str(), response.length() + 1);
                    *size = response.length();
                
                    return noError;
                }
                

                So I delete size next time.

                LabVIEW front result :
                5.JPG

                LabVIEW diagram :
                6.jpg

                JKSHJ 1 Reply Last reply
                0
                • U UvQtcYZJuD7J5VW7

                  @JKSH Great ! It works.

                  Now, my data are well returned (copied) in LabVIEW but at the end of the execution, LabVIEW crashes with the following error code : DAbort 0xF50EFD7B in MemoryManager.cpp

                  setPower function into Qt DLL :

                  int myClass::setPower(char *receivedMessageString, char *responseMessageString, size_t *size)
                  {
                      // Error codes
                      int noError = 0;
                      int buffToSmall = 10;
                  
                      QByteArray receivedMessage(receivedMessageString, strlen(receivedMessageString));
                  
                      std::string response(receivedMessage.constData(), receivedMessage.length());
                  
                      if(*size <= response.length())
                      {
                          return buffToSmall;
                      }
                  
                      qstrncpy(responseMessageString, response.c_str(), response.length() + 1);
                      *size = response.length();
                  
                      return noError;
                  }
                  

                  So I delete size next time.

                  LabVIEW front result :
                  5.JPG

                  LabVIEW diagram :
                  6.jpg

                  JKSHJ Offline
                  JKSHJ Offline
                  JKSH
                  Moderators
                  wrote on last edited by
                  #8

                  @UvQtcYZJuD7J5VW7 said in QByteArray to LabVIEW Byte Array conversion:

                  int myClass::setPower(char *receivedMessageString, char *responseMessageString, size_t *size)

                  Don't use char *... you can't control the memory allocation with char *.

                  Use LStrHandle like I said before. And you don't need the size parameter.

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  U 1 Reply Last reply
                  2
                  • JKSHJ JKSH

                    @UvQtcYZJuD7J5VW7 said in QByteArray to LabVIEW Byte Array conversion:

                    int myClass::setPower(char *receivedMessageString, char *responseMessageString, size_t *size)

                    Don't use char *... you can't control the memory allocation with char *.

                    Use LStrHandle like I said before. And you don't need the size parameter.

                    U Offline
                    U Offline
                    UvQtcYZJuD7J5VW7
                    wrote on last edited by UvQtcYZJuD7J5VW7
                    #9

                    @JKSH Sorry but I don't see how can I use LStrHandle in Qt because I need to include Labview extcode.h and when I include it, I get errors about my compiler (platdefines.h doens't recognize my compiler when I'm in Qt Creator).

                    JKSHJ 1 Reply Last reply
                    0
                    • U UvQtcYZJuD7J5VW7

                      @JKSH Sorry but I don't see how can I use LStrHandle in Qt because I need to include Labview extcode.h and when I include it, I get errors about my compiler (platdefines.h doens't recognize my compiler when I'm in Qt Creator).

                      JKSHJ Offline
                      JKSHJ Offline
                      JKSH
                      Moderators
                      wrote on last edited by
                      #10

                      @UvQtcYZJuD7J5VW7 said in QByteArray to LabVIEW Byte Array conversion:

                      I need to include Labview extcode.h

                      Yes, that's right.

                      and when I include it, I get errors about my compiler (platdefines.h doens't recognize my compiler when I'm in Qt Creator).

                      Then you just need to address the error.

                      If you use MSVC, it will work fine out-of-the-box.

                      If you want to use MinGW, you can modify platdefines.h and add these 2 lines to define your compiler:

                      ...
                      #elif defined(__GNUC__)       // <-- Add this
                          #define Compiler kGCC     // <-- Add this
                      #else
                          #error "We don't know the Compiler"
                      #endif
                      

                      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                      1 Reply Last reply
                      1

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved