Hoe gebruik ik MultiByteToWideChar?

Ik wil om te zetten in een normale string een wstring. Voor dit, ik probeer gebruik te maken van de Windows API-functie MultiByteToWideChar.
Maar het werkt niet voor mij.

Hier is wat ik heb gedaan:

string x = "This is c++ not java";
wstring Wstring;
MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , x.size() , &Wstring , 0 ); 

De laatste regel maakt de compiler error:

'MultiByteToWideChar' : cannot convert parameter 5 from 'std::wstring *' to 'LPWSTR'

Hoe los ik dit fout?

Ook, wat moet de waarde van het argument cchWideChar? 0 oke?

  • U kan niet geven een pointer naar std::wstring voor deze functie.
  • plus1 voor de Zeer nuttige vraag.

 

4 Replies
  1. 38

    Dient u contact op te MultiByteToWideChar twee keer:

    1. De eerste oproep aan MultiByteToWideChar wordt gebruikt om de buffer grootte die u nodig hebt voor de brede reeks. Kijk op De documentatie van Microsoft; er staat:

      Als de functie slaagt en cchWideChar 0 is, is de geretourneerde waarde is de vereiste grootte, in tekens, voor de buffer aangegeven door lpWideCharStr.

      Dus te maken MultiByteToWideChar geven u de gewenste afmetingen, geef 0 op als de waarde van de laatste parameter, cchWideChar. U moet ook doorgeven NULL als de vorige, lpWideCharStr.

    2. Het verkrijgen van een niet-const buffer groot genoeg is voor het brede reeks, met behulp van de buffer grootte van de vorige stap. Geef deze buffer naar de andere oproep te MultiByteToWideChar. En deze keer, de laatste argument moet de werkelijke grootte van de buffer, en niet 0.

    Een vaag voorbeeld:

    int wchars_num = MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , -1, NULL , 0 );
    wchar_t* wstr = new wchar_t[wchars_num];
    MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , -1, wstr , wchars_num );
    //do whatever with wstr
    delete[] wstr;

    Let ook op het gebruik van -1 als de cbMultiByte argument. Dit zal de resulterende tekenreeks null-terminated, wat u van omgaan met hen.

    • +1 voor het accentueren van de noodzaak voor het aanroepen van de MultiByteToWideChar twee keer, wat essentieel is voor de karakterset conversie functies.
    • eran wat is het verschil tussen wchar_t* en LPTSTR ?
    • Gupta, als je samenstellen met Unicode, dan is het precies hetzelfde. In multi-byte bouwen, LPTSTR zou uitbreiden naar een reguliere char*. Met behulp van deze macro ‘ s kunt u zowel Unicode-als niet-Unicode-bouwt. Ik kan niet denken van een reden om dat te doen deze dagen, maar, en sinds Unicode is nu de standaardinstelling in de VS, een van hen.
    • OWCH! Er is niet zoiets als free[], en zelfs als die er wel was, zou ik nooit vergeeft zo ‘ n code. Gebruik een std::vector<wchar_t> de juiste wijze aangepast.
    • Owch inderdaad… dat is waarom ik zei het op zo vaag. Was in een haast. Vaste antwoord, bedankt.
    • De owch deel van dat was niet de free[], het was het LEK MIDDELEN EN OVERLOOP MIJN BUFFERS EN CORRUPTE MIJN HOOP van het gebruik van new en delete direct. Gebruik std::vector<wchar_t>.
    • Ik probeerde vereenvoudigd Chinees (GB18030) en het werkt als verwacht. Heeft u CP_UTF8 Chinese codepage?
    • het zou kunnen werken nu – maar dat was een tijdje geleden postte ik dat. Blij dat het werkt! 😉

  2. 1

    Tweede vraag over, deze ochtend!

    WideCharToMultiByte() en MultiByteToWideChar() een pijn te gebruiken. Elke conversie vereist twee oproepen aan de routines en je hebt om te kijken na de toewijzing van/geheugen vrijmaken en ervoor te zorgen dat de snaren correct zijn afgesloten. U moet een wrapper!

    Ik heb een handige C++ wrapper op mijn blog, hier, waarin u bent van harte welkom om te gebruiken.

    Hier is de andere vraag deze ochtend

  3. 1

    Kunt u proberen deze oplossing hieronder. Ik heb het getest, het werkt, het detecteren van speciale tekens (bijvoorbeeld: º ä á ç ) en werkt op Windows XP, Windows 2000 met SP4 of later, Windows 7, 8, 8.1 en 10.
    Met behulp van std::wstring in plaats new wchar_t /delete, verminderen we de problemen met lekken middelen, buffer overflow en corrupte hoop.

    dwFlags was ingesteld op MB_ERR_INVALID_CHARS te werken op Windows 2000 met SP4 of hoger, Windows XP. Als deze vlag is ingesteld, stelt u de functie in stilte daalt illegale code punten.

    std::wstring ConvertStringToWstring(const std::string &str)
    {
        if (str.empty())
        {
            return std::wstring();
        }
        int num_chars = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str.c_str(), str.length(), NULL, 0);
        std::wstring wstrTo;
        if (num_chars)
        {
            wstrTo.resize(num_chars);
            if (MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str.c_str(), str.length(), &wstrTo[0], num_chars))
            {
                return wstrTo;
            }
        }
        return std::wstring();
    }
  4. 0

    De functie niet kunnen nemen van een pointer naar een C++ string. Het verwacht een pointer naar de buffer van de brede tekens van voldoende grootte – u moet toewijzen van deze buffer jezelf.

    string x = "This is c++ not java";
    wstring Wstring;
    Wstring.resize(x.size());
    int c =  MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , x.size() , &Wstring[0], 0 ); 
    • MultiByteToWideChar verwacht een parameter van het type wchar_t*. Wstring is van het type std::wstring – en kan dus niet worden doorgegeven aan MultiByteToWideChar (zelfs niet een pointer naar het). Maar het goede nieuws is, dat std::wstring intern slaat gegevens op als wchar_t* en biedt twee functies om toegang te krijgen tot deze interne gegevens: data() (dat is hier) en c_str().
    • merk op dat wstring.gegevens() retourneert een const wchar_t maxlen*, die accoding te cplusplus.com mag niet rechtstreeks worden gewijzigd (u weet waarschijnlijk beter dan ik, wat zou het effect van dit te doen). OTOH, het laatste argument van MBTWC zijnde 0, niets zal worden geplaatst in die buffer toch…
    • Oeps, je hebt helemaal gelijk over de terugkeer van de waarde van const.
    • Het werkt niet op die manier, wstring maakt gebruik van 32-bits tekens, terwijl win32 gebruik van 16-bits unicode-tekens…

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *