QByteArray to LabVIEW Byte Array conversion
-
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.
-
@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 beingchar *
.When you talk about "Byte Array" at various points in your question, how do we know which of
LV Byte Array
orQByteArray
you mean? I don't know what the rules for a LabView Byte array might be.Qt
QByteArray
s 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 theQByteArray
's count/length, and is only there to make it a bit interoperable withQString
s. 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.
-
- Do not return
QByteArray::constData()
!!! Your QByteArray gets destroyed at the end of your functions, so your returned pointer becomes a dangling pointer. - If your data can contain '\0', then you cannot pass it as
const char *
("C String Pointer" in LabVIEW). You must pass it as anLStrHandle
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
- Do not return
-
@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 haveCStr
orPascal String
.
What do you mean when you said You must pass it as anLStrHandle
? -
@UvQtcYZJuD7J5VW7 said in QByteArray to LabVIEW Byte Array conversion:
In Call Library Function Node, we can't get
LStrHandle
in return type. We juste haveCStr
orPascal 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
?Note: If you pass
receiveMessageString
as a String Handle instead of a C String Pointer, then you don't need thelength
argument. -
@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 :
LabVIEW diagram :
-
@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 withchar *
.Use
LStrHandle
like I said before. And you don't need the size parameter. -
@JKSH Sorry but I don't see how can I use
LStrHandle
in Qt because I need to include Labviewextcode.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). -
@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