Congratulations to our 2022 Qt Champions!

[Closed] Passing QString's to C external libraries

  • Hi! I just noticed a behavior that is very strange when using QString's and an external C++ library. What I've done is simply to pass a QString to a function of an external library this way:

    @QString qString("test");
    const char* _qString = qString.toStdString().c_str();

    What is happening is something very very strange, my suspect is that it's somehow related to implicit sharing (but I'm not sure). The output of this piece of code I place for debugging inside externalFunction(const char* clientPath):

    @fprintf(stderr, "1: %s.\n", clientPath);
    std::string rootPath, leafName, fileExt;
    char* _rootPath = new char[strlen(clientPath) + 1];
    strcpy(_rootPath, clientPath);
    fprintf(stderr, "_rootPath: %s.\n", _rootPath);
    rootPath = _rootPath;
    rootPath[0] = 'A';
    fprintf(stderr, "1b: %s.\n", clientPath);
    fprintf(stderr, "Address of clientPath: %x.\n", clientPath);
    fprintf(stderr, "Address of _rootPath: %x.\n", _rootPath);
    fprintf(stderr, "Address of rootPath: %x.\n", rootPath.c_str());@


    1: /home/luca/2.jpg.
    _rootPath: /home/luca/2.jpg.
    1b: Ahome/luca/2.jpg.
    Address of clientPath: 8751de4.
    Address of _rootPath: 874fcc8.
    Address of rootPath: 8751de4.

    Any idea why this is happening precisely and how I can avoid it? Is this related to Qt?

  • The problem is this line: _const char* qString = qString.toStdString().c_str();, because it create a temporary std::string that will go out of scope before you can use it (so you will have a dangling pointer).

    You can achieve what you want something like this:
    void c_func(char* str) {
    printf("%s\n", str);

    int main()
    QString s("Test QString to char pointer");

    char *ptr = strdup(s.toLocal8Bit().data()); //duplicate the returned c-style string


    QString s0("This also work");

    c_func(s0.toLocal8Bit().data()); //or make the temporary in your function call - this way the temp variable should be valid through the function call

    return 0;

  • Indeed I solved using toAscii().constData(). Anyway I don't think it was going out of scope... The function I invoked was not asynchronous...

Log in to reply