PDA

View Full Version : Converting QString to char* in onl line



hubbobubbo
9th December 2009, 13:14
I have a QString that I need to pass as qrgument to a C dll wanting a char*.

When I do like this:
char* str_p = myQString.toAscii().constData();
qDebug("%s", str_p );

It prints ???????? all over the screen so the pointer is crap.

However if I do like this:
QByteArray ba = myQString.toAscii();
char* str_p = ba.constData();
qDebug("%s", str_p);

It works just fine.

I really would like to have the QString to char* conversion as a one liner, why does the first approach fail?

drhex
9th December 2009, 13:20
The first version fails because you get a pointer to a temporary variable that is forgotten by the time you use your pointer. In the second case, the QByteArray is still around.

hubbobubbo
9th December 2009, 16:30
thanks drhex

So can I assume that there is no oneliner to achive this?

schnitzel
9th December 2009, 20:28
char* str_p = myQString.toAscii().constData();
qDebug("%s", str_p );


when I try to compile your code, I get:
C:/dev/testproj/mainwindow.cpp:11: error: invalid conversion from `const char*' to `char*'

instead, do the following:


const char* str_p = myQString.toAscii().constData();
qDebug("%s", str_p );


This gives me the correct string.

schnitzel
9th December 2009, 20:48
The first version fails because you get a pointer to a temporary variable that is forgotten by the time you use your pointer. In the second case, the QByteArray is still around.

Is this really true?

myString.toAscii() will return a QByteArray and then myString.toAscii.constData() will return a const char*.

from Qt Documentation:



const char * QByteArray::constData () const

Returns a pointer to the data stored in the byte array. The pointer can be used to access the bytes that compose the array. The data is '\0'-terminated. The pointer remains valid as long as the byte array isn't reallocated or destroyed.

This function is mostly useful to pass a byte array to a function that accepts a const char *.

Note: A QByteArray can store any byte values including '\0's, but most functions that take char * arguments assume that the data ends at the first '\0' they encounter.

See also data() and operator[]().

squidge
9th December 2009, 21:37
It's true. QString's toAscii() returns a QByteArray. That QByteArray will be destroyed by the time the char * pointer is assigned str_p, unless you store it somewhere (as in the second version). The contents may or may not be what your expecting because of this, or it may just crash your program.

The Qt documentation talks about the const_data that QByteArray returns, which is also true, but that pointer is no good if you destroy the QByteArray holding that pointer.

hubbobubbo
10th December 2009, 09:31
Thanks for all the replies, seems like the simple question spotted a slightly tricky problem.

My assumption is simply that I will not be able to convert my QStrings into char* inside the function call to the dll that expects a char*, instead I have to do the intermediate step to convert to ByteArray for all variables.

//Impossible
void myQTFunc(QString str1)
{
myDllfunc(str1.toAscii().constData());
}

//Possible
void myQTFunc(QString str1)
{
QByteArray ba1 = str1.toAscii();
myDllfunc(ba1.constData);
}

So does anyone know if the conversion from QString to QByte array involves any copying? The QString is Unicode right? Does that mean that the toAscii() conversion creates a local copy of the string contents as a C char array?

I also assume that the constData() just returns the internal char* from QByteArray and that it does not involve any copying of data, does this sound correct?

schnitzel
10th December 2009, 18:05
when you use the QByteArray::constData() method, a shallow copy takes place, which is very fast, i.e. it is just getting a pointer and incrementing a reference count. QByteArray::data() is a deep copy, which is a real copy and thus slower.

Just read the documentation on QByteArray::constData() - it is explained very well.

JohannesMunk
11th December 2009, 01:27
What about using this directly as parameter to your call?



str.toStdString().c_str();


HIH

Johannes

hubbobubbo
11th December 2009, 09:50
Ok this seemed to work, nice.

However the doc says that:
This operator is only available if Qt is configured with STL compatibility enabled.

Is this always the default setting? I need this to run on Win32, Windows Mobile and S60. Can I assume that the STL will always be supported.

JohannesMunk
11th December 2009, 11:45
How are you going to use a c dll on all those platforms?

And I have no idea, if STL is available for those platforms. Sorry!

Johannes