vswprintf() und Argumentenliste mit std::wstring



  • hallo,

    ich habe das Problem das bei einer Funktion wie ...

    void meinefunction(std::wstring sFormat, ...);
    

    die Anwendung abstürtzt wenn ich bei den Argumenten einen std::wstring verwende, zum Beispiel ...

    std::wstring sObst(TEXT("Apfel"));
    meinefunction(TEXT("Es sind 3 %s vorhanden."), sObst);
    

    Es hilft auch nichts wenn ich sObst.c_str(); verwende. Kompilieren geht aber die Anwendung stürtzt ab. Der Debugger zeigt an das es an einem ungültigen Pointer liegt. Der Absturz tritt beim Aufruf von der Funktion vswprintf() auf die ich für das durchgehen der Argumente verwende.

    Weiss jemand eine Lösung? Die vswprintf() ist wohl nicht unbedingt eine C++ Funktion, aber wie könnte ich es sonst machen ohne alle in TCHARs zu konvertieren.



  • Poste mal den code von meinefunction.



  • MultivitaminSaft schrieb:

    aber wie könnte ich es sonst machen ohne alle in TCHARs zu konvertieren.

    Was willst du genau machen? Sorry, ich kenne die Funktion vswprintf() nicht.
    Und mehr Code wäre vielleicht nützlich...



  • Hier ist die Funktion die "meinefunction" entspricht. Vorher habe ich nur TCHAR benutzt und wollte jetzt meine Klassen auf std::wstring umstellen. Die cl...() Funktionen gehören zu einer Library.

    Die MessageBox ist da um zu sehen was zu letzt ausgeführt wurde. In dem Fall wird die erste angezeigt aber die zweite nicht mehr, das bedeutet das es bei vswprintf() knallt.

    void CVSyncClass::ProtocolOutput(bool bTimestamp, int iMessageType, wstring sFormat, ...) {
    
    	if(sFormat.empty()) { return; }		
    
    	if(!cl_GetOutputMode() && (iMessageType == VSYNCCLASS_MSG_SYSTEM)) { return; }
    
    	TCHAR		sParameterText[1024];
    	wcscpy_s(sParameterText, 1024, sFormat.c_str());
    
    	va_list		alArguments;	
    	TCHAR		sOutputString[1024];
    
    	va_start(alArguments, sParameterText);	
    
    MessageBox(NULL,TEXT("test"),TEXT("test"), MB_OK);
    	vswprintf(sOutputString,sizeof(sOutputString)/sizeof(TCHAR), sParameterText, alArguments);			
    MessageBox(NULL,TEXT("test"),TEXT("test"), MB_OK);
    
    	va_end(alArguments);	
    
    	wstring		sOutputStringW;
    	sOutputStringW.append(sOutputString);
    
    	cl_AddMessage(bTimestamp, iMessageType, sOutputStringW.c_str());
    
    	}
    

    Visual Studio zeigt den Fehler in einer output.c an die wohl von der vswprintf() verwendet wird. Dabei wird bei text.wz ein "0xcccccc (Schlechtes Ptr)" angezeigt, knallen tuts dann bei while(i-- && *pwch)

    if (text.wz == NULL) /* NULL passed, use special string */
                            text.wz = __wnullstring;
                        bufferiswide = 1;
                        pwch = text.wz;
                        while (i-- && *pwch)
                            ++pwch;
                        textlen = (int)(pwch - text.wz);       /* in wchar_ts */
    

    Wie vorher schon schrieb, hab ich auch schon .c_str() probiert. Was ist an einem .c_str() anders als an einem TCHAR Pointer außer das der von c_str() const ist?



  • 1. Du kannst keine C++-Objekte (genauer: keine non-PODs) über die Ellipse (...) übergeben.
    2. Beim Aufruf von va_start übergibst Du nicht den letzten Parameter vor der Ellipse, sondern irgendeine Stackvariable.

    Wenn Du diese Probleme korrigierst, sollte es mit der Übergabe von Zeigern und Integralen keine Probleme geben. Generell solltest Du aber von der Verwendung der Ellipse absehen.



  • LordJaxom schrieb:

    Du kannst keine C++-Objekte (genauer: keine non-PODs) über die Ellipse (...) übergeben.

    Man kann schon. Nur muss man wissen, was auf dem Stack steht! 🤡
    Dir printf Derivate können in keinem Fall damit umgehen, das %s einen Pointer erwartet!



  • Martin Richter schrieb:

    Man kann schon. Nur muss man wissen, was auf dem Stack steht! 🤡

    Und das ist vom Standard nicht abgedeckt.

    Wenn ich von "man kann" spreche, meine ich i.A. auch die definiertheit des daraus resultierenden Verhaltens 🙂



  • LordJaxom schrieb:

    Generell solltest Du aber von der Verwendung der Ellipse absehen.

    Gibt es denn eine Alternative dazu wenn man sowas vergleichbares umsetzen wollte?


  • Mod

    MultivitaminSaft schrieb:

    LordJaxom schrieb:

    Generell solltest Du aber von der Verwendung der Ellipse absehen.

    Gibt es denn eine Alternative dazu wenn man sowas vergleichbares umsetzen wollte?

    Es gibt verschiedene Möglichkeiten, z.B. per Operatorüberladung wie in boost.format


Anmelden zum Antworten