I think the decision depends on the type of characters that need to be converted, and whether to integrate / call the C-style function with arguments of type "char *".
- If a C-style function needs to be integrated / called, do not use toStdString (), followed by c_str (), since the return type is "const char *", which is not suitable for the C-style function.
- Use toLatin1 () followed by data () for ASCII characters.
- Use toLocal8Bit () or toUtf8 () followed by data () for other UTF8 characters than ASCII.
If several solutions can be used for your particular case, their performance levels may differ slightly, which I have not tested.
The following test program shows how to use these solutions:
#include <QCoreApplication> #include <QDebug> // This is a C-style test function which needs an argument of type "char *": void my_c_func(char * my_c_str) { printf(" my_c_str[%s]\n", my_c_str); } // This is a program which tests the conversion from "QString" to "char *": int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // Case 1: ASCII characters // ======================== QString qString1 = "French"; qDebug().nospace().noquote() << "qString1[" << qString1 << "]"; // qString1[French] // Solution 1.1: to Latin1 QByteArray, followed by data() in 2 steps: QByteArray latin1BAString1 = qString1.toLatin1(); char * latin1_c_str1 = latin1BAString1.data(); qDebug().nospace().noquote() << "latin1_c_str1[" << latin1_c_str1 << "]"; // latin1_c_str1[French] my_c_func(latin1_c_str1); // Solution 1.2: to local 8-bit QByteArray, followed by data() in 2 steps: QByteArray local8bitBAString1 = qString1.toLocal8Bit(); char * local8bit_c_str1 = local8bitBAString1.data(); qDebug().nospace().noquote() << "local8bit_c_str1[" << local8bit_c_str1 << "]"; // local8bit_c_str1[French] my_c_func(local8bit_c_str1); // Solution 1.3: to UTF8 QByteArray, followed by data() in 2 steps: QByteArray utf8BAString1 = qString1.toUtf8(); char * utf8_c_str1 = utf8BAString1.data(); qDebug().nospace().noquote() << "utf8_c_str1[" << utf8_c_str1 << "]"; // utf8_c_str1[French] my_c_func(utf8_c_str1); // !!! Try: Solution 1.4: to std::string , followed by c_str() in 2 steps: std::string stdString1 = qString1.toStdString(); const char * stdstring_c_str1 = stdString1.c_str(); // "const" must be used ! qDebug().nospace().noquote() << "stdstring_c_str1[" << stdstring_c_str1 << "]"; // stdstring_c_str1[French] // invalid conversion from 'const char*' to 'char*': ---> NOT GOOD for use by a C-style function !!! // my_c_func(stdstring_c_str1); qDebug() << ""; // Case 2: Non-ASCII characters // ============================ QString qString2 = "français"; qDebug().nospace().noquote() << "qString2[" << qString2 << "]"; // qString2[français] // !!! Try: Solution 2.1: to Latin1 QByteArray, followed by data() in 2 steps: QByteArray latin1BAString2 = qString2.toLatin1(); char * latin1_c_str2 = latin1BAString2.data(); qDebug().nospace().noquote() << "latin1_c_str2[" << latin1_c_str2 << "]"; // latin1_c_str2[fran?ais] ---> NOT GOOD for non-ASCII characters !!! my_c_func(latin1_c_str2); // Solution 2.2: to Local 8-bit QByteArray, followed by data() in 2 steps: QByteArray local8bitBAString2 = qString2.toLocal8Bit(); char * local8bit_c_str2 = local8bitBAString2.data(); qDebug().nospace().noquote() << "local8bit_c_str2[" << local8bit_c_str2 << "]"; // local8bit_c_str2[français] my_c_func(local8bit_c_str2); // Solution 2.3: to UTF8 QByteArray, followed by data() in 2 steps: QByteArray utf8BAString2 = qString2.toUtf8(); char * utf8_c_str2 = utf8BAString2.data(); qDebug().nospace().noquote() << "utf8_c_str2[" << utf8_c_str2 << "]"; // utf8_c_str2[français] my_c_func(utf8_c_str2); // !!! Try: Solution 2.4: to std::string, followed by c_str() in 2 steps: std::string stdString2 = qString2.toStdString(); const char * stdstring_c_str2 = stdString2.c_str(); // "const" must be used ! qDebug().nospace().noquote() << "stdstring_c_str2[" << stdstring_c_str2 << "]"; // stdstring_c_str2[français] // invalid conversion from 'const char*' to 'char*': ---> NOT GOOD for use by a C-style function !!! // my_c_func(stdstring_c_str2); return a.exec(); }
The above code has been tested using Qt 5.4 for Linux.
The second question involved in this question is whether we can combine functions during this two-step conversion process:
<myQString>.to<AnotherClass>().<getCPointer>(); // OK or not?
I think it depends on "AnotherClass" and on the type of characters that need to be converted. Based on some documentation on QString, QByteArray and std :: string, it seems safe to write:
<myQString>.toStdString().c_str(); // OK.
<myQString>.toUtf8().data(); // Should be OK as QString is Unicode string.
But the following lines should be avoided:
<myQString>.toLocal8Bit().data(); // May crash if the converted QByteArray object is undefined !
<myQString>.toLatin1().data(); // May crash if the converted QByteArray object is undefined !