2016-04-11 21 views
0

Mein Projekt wird vom Multi-Byte-Zeichensatzprojekt in den Unicode-Zeichensatz geändert. Daher müssen viele Variablentypen konvertiert werden, um dem Typ des Parameters zu entsprechen. Ich habe eine Funktion erstellt, um char[] in LPWSTR umzuwandeln. Unten ist der Code:Schreibort für Zugriffsverletzung in einer Funktion des Unicode-Zeichensatzprojekts

LPWSTR CharFunction::CharToLPWSTR(char charVariable[]) 
{ 
    LPWSTR returnVariable; 
    MultiByteToWideChar(CP_UTF8, 0, charVariable, -1, returnVariable, 2048); 
    return returnVariable; 
} 

Allerdings gibt es

Unbehandelte Ausnahme bei 0x77a9007e in xxxx.exe: 0xC0000005: Zugriffsverletzung Schreibort 0x7712311e.

fand ich, dass es erstmals ausgeführt werden können, aber der Fehler tritt bei zweiten Mal bei

MultiByteToWideChar(CP_UTF8, 0, charVariable, -1, returnVariable, 2048); 

ich verbringen 3 Stunden debug, aber kein Glück. Ich würde es begrüßen, wenn mir jemand helfen könnte, diesen Fehler zu beheben. Vielen Dank.

Aktualisiert:

Unten ist der Code-Schnipsel die Variable und das Bestehen des Wertes an die Funktion zu erklären.

LPWSTR  g_szSystemIni; 
char drive[_MAX_DRIVE]; 
char dir[_MAX_DIR]; 
_splitpath_s(szModuleName_converted, drive, _MAX_DRIVE, dir, _MAX_DIR, fname, _MAX_FNAME, ext, _MAX_EXT); 
lstrcpy(g_szSystemIni,charfunction.CharToLPWSTR(drive)); 
lstrcat(g_szSystemIni,charfunction.CharToLPWSTR(dir)); 
+0

Wo weisen Sie den Zielpuffer zu? – ZDF

+0

10 'returnVariable' zeigt nirgendwo hin, aber Sie haben Windows gesagt, dass es 2048 Zeichen lang ist! – user657267

+0

Wenn Sie MFC verwenden, verwenden Sie einfach CStringW: CStringW ("Ascii"). – ZDF

Antwort

1

Im angegebenen Code reservieren Sie keinen Speicherplatz für returnVariable.

Eine einfache new könnte funktionieren, aber in Ihrem Fall wird dies dazu führen, dass Mechanismen schwieriger zu entziehen.

LPWSTR CharFunction::CharToLPWSTR(char charVariable[]) 
{ 
    const int BUFFER_SIZE = 2048; 
    LPWSTR returnVariable = new WCHAR[BUFFER_SIZE]; 
    // could assign it to and return a unique_ptr 
    MultiByteToWideChar(CP_UTF8, 0, charVariable, -1, returnVariable, BUFFER_SIZE); 
    return returnVariable; 
} 

Das kann am besten sein, die Funktion Signatur zu modifizieren und erlauben es dem Anrufer einen Stapelpuffer zuzuweisen (in einem ähnlichen vergeblich auf das Eingabeargument). Sie können den Rückgabetyp für eine einfachere Verwendung beibehalten.

LPWSTR CharFunction::CharToLPWSTR(char charVariable[], wchar_t returnVariable[]) 
{ 
    const int BUFFER_SIZE = 2048; 
    MultiByteToWideChar(CP_UTF8, 0, charVariable, -1, returnVariable, BUFFER_SIZE); 
    return returnVariable; 
} 

Und im aufrufenden Code;

LPWSTR g_szSystemIni; 
char drive[_MAX_DRIVE]; 
wchar_t buffer[2048]; 
// ... 
lstrcpy(g_szSystemIni, charfunction.CharToLPWSTR(drive, buffer)); 
+0

Es funktioniert. Ich danke dir sehr! ^^ –

-1

Vom MSDN

Vorsicht die Funktion MultiByteToWideChar Durch das unkorrekte Verwendung die Sicherheit Ihrer Anwendung beeinträchtigen können. Der Aufruf dieser Funktion kann leicht zu einem Pufferüberlauf führen, da die Größe des durch lpMultiByteStr angegebenen Eingabepuffers gleich der Anzahl der Bytes in der Zeichenfolge ist, während die Größe des durch lpWideCharStr angegebenen Ausgabepuffers gleich der Anzahl der Zeichen ist. Um einen Pufferüberlauf zu vermeiden, muss Ihre Anwendung eine Puffergröße angeben, die für den vom Puffer empfangenen Datentyp geeignet ist.

Stellen Sie sicher, dass Sie die richtigen Werte als 4. und 6. Argument senden. Das vierte Argument ist die Puffergröße oder Anzahl der Bytes in der ersten Zeichenfolge und das letzte Argument ist die Anzahl der konvertierten Zeichen. und überprüfen Sie, ob der Ausgabezeiger genügend Speicher hat.