Convert QString to wchar_t*



  • How to convert from QString to wchar_t*? I have a function that asks for a wchar_t* and I need to convert a QString I have to pass as argument.



  • This post is deleted!

  • Qt Champions 2017

    hi @gkosi

    two comments to your code:

    1. the array needs to be at least the size of the sting contents
    2. the array is not null terminated, so you should make it one element larger and set this one to zero

    Regards



  • I did it like this:

        // MAX_FILENAME_SIZE = 2048
        wchar_t filenameW[MAX_FILENAME_SIZE];
        int length = filename.left(MAX_FILENAME_SIZE - 1).toWCharArray(filenameW);
        filenameW[length] = '\0';
    

    Any tips for improvement?



  • Since you have to use a container anyway, instead of a raw array I'd just use std::wstring:

    QString testStr("Test");
    std::wstring  testWstring  = testStr.toStdWString();
    functionThatTakesWcharPointer(testWstring.c_str());
    


  • @VRonin c_str returns a const right? It's not a const that it asks for, so I'm getting an error saying that can't convert from const wchar_t* to wchar_t*.

    ... I just put a const_cast<wchar_t *> and it compiled but the string isn't right, it's like this:

    0_1531804584324_5d3e913f-d6ed-4153-8e0b-efaa5aeb84e9-image.png



  • @Mr-Gisa

    Just use like this:

    QString qString("Test");
    wchar_t *wc = reinterpret_cast<wchar_t *>(qString.data())
    const wchar_t *cwc = reinterpret_cast<const wchar_t *>(qString.utf16());
    

  • Qt Champions 2017

    Hi @Devopia53,

    Your code assumes that wchar_t is 16 bit wide. That is not always the case, see the already mentioned docs.



  • A function that takes non-const wchar_t* is very dodgy! it should have no way of knowing the maximum allocated memory to that pointer/array so it is either allocating it internally (hence our discussion has been pointless so far) or that function is terribly designed and it's just a ticking time bomb.
    Can I ask what that function does?



  • @VRonin It's not a function actually, sorry for the bad information, it's a struct.

    struct RAROpenArchiveDataEx
    {
      char         *ArcName;
      wchar_t      *ArcNameW;
      unsigned int  OpenMode;
      unsigned int  OpenResult;
      char         *CmtBuf;
      unsigned int  CmtBufSize;
      unsigned int  CmtSize;
      unsigned int  CmtState;
      unsigned int  Flags;
      UNRARCALLBACK Callback;
      LPARAM        UserData;
      unsigned int  Reserved[28];
    };
    

    ArcNameW
    Input parameter which should point to zero terminated Unicode string containing the archive name or NULL if Unicode name is not specified.



  • Who has the responsibility of managing memory allocation of those struct members?



  • 0_1531813356323_2919dca9-6d7f-4076-94ce-b52c80d4630a-image.png
    I couldn't find the docs online.

    RAROpenArchiveEx pretty much.

    You can download the dlls, examples and the docs on the official website: https://www.rarlab.com/rar/UnRARDLL.exe



  • Ok, got it now, looks like it is used-as-const so the const_cast<wchar_t *>(testWstring.c_str()) should work. The string you see in the debugger might just be because you are trying to read the variable past its lifetime, I wouldn't worry about it



  • @VRonin It's not working. After calling RAROpenArchiveEx it writes to RAROpenArchiveDataEx.OpenResult and the result should be ERAR_SUCCESS but it's returning ERAR_EOPEN and isn't right. For some reason it's only working the way I did before:

        // MAX_FILENAME_SIZE = 2048
        wchar_t filenameW[MAX_FILENAME_SIZE];
        int length = filename.left(MAX_FILENAME_SIZE - 1).toWCharArray(filenameW);
        filenameW[length] = '\0';
    


  • @Mr-Gisa said in Convert QString to wchar_t*:

    ERAR_EOPEN

    I don't know what state your code is in. But ERAR_EOPEN is some kind of "file is already open" error on a RAR archive, and it hardly seems likely that could be generated as a direct result of something about converting strings, does it to you?



  • @JonB The code I posted worked because it's converting the path for the rar file correctly, altough when I try the alternatives here I get a weird string and not a correct path/rar file.



  • @Mr-Gisa said in Convert QString to wchar_t*:

    I get a weird string

    I suspect you are holding a pointer to a temporary variable. If you are doing something like this, you are doing it wrong:

    void fillName(RAROpenArchiveDataEx* rar, const QString& fileName){
    rar->ArcNameW = const_cast<wchar_t *>(fileName.toStdWString().c_str());
    }
    

    As the temporary std::wstring will be destroyed and rar->ArcNameW will contain garbage



  • bool RAR::open(RAR::OpenMode mode)
    {
        RAROpenArchiveDataEx openArchiveData;
        memset(&openArchiveData, 0, sizeof(openArchiveData));
    
        openArchiveData.ArcName = 0;
    
        auto archive = const_cast<wchar_t *>(mArchive.toStdWString().c_str());
    
        openArchiveData.ArcNameW = archive;
        openArchiveData.OpenMode = mode;
        openArchiveData.CmtBuf = 0;
        openArchiveData.CmtBufSize = 0;
        openArchiveData.Callback = 0;
        openArchiveData.UserData = 0;
    
        mHandle = RAROpenArchiveEx(&openArchiveData);
        mResult = openArchiveData.OpenResult;
    
        if (mResult != ERAR_SUCCESS) {
            return false;
        }
    
        scan();
    
        return true;
    }
    


  • @Mr-Gisa said in Convert QString to wchar_t*:

    auto archive = const_cast<wchar_t *>(mArchive.toStdWString().c_str());

    Boom! exactly as I supected!

    auto archiveWString = mArchive.toStdWString();
    auto archive = const_cast<wchar_t *>(archiveWString.c_str());
    


  • @VRonin said in Convert QString to wchar_t*:

    auto archiveWString = mArchive.toStdWString();
    auto archive = const_cast<wchar_t *>(archiveWString.c_str());

    Yay now its working. Thx.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.