TUnicodeString.vprintf wie debuggen



  • Hallo zusammen

    Ich habe ein Problem (Zugriffsverletzung) wenn ich bei TUnicodeString.vprintf() AnsiStrings mit %S und einer Länge von ca 650 Zeichen hinzufüge.
    Was muß ich wo einstellen, daß ich vprintf() debuggen kann.

    String TLog::AddFmtDbg(String sDbg, const wchar_t* format, ...)
    {
        va_list vaPtr;
        va_start(vaPtr, format);
    
        logData.sData.vprintf(format, vaPtr); //Hier gibt es die Zugriffsverletzung
    }
    

    Verwende Builder 2010.
    MfG Stephan



  • Also ich bin nun in ustring.cpp fündig geworden.
    Allerdings wirft nun die Funktion vsnwprintf() die Exception.
    Mit folgendem Code kann das Problem nachvollzogen werden:

    int vpf(wchar_t *fmt, ...)
    {
        va_list argptr;
        int cnt;
        va_start(argptr, fmt);
        String Temp;
    
        wchar_t *temp;
    
        int size = vsnwprintf(NULL, 0, fmt, argptr);
        temp = new wchar_t[size+1];
        vsnwprintf(temp, size + 1, fmt, argptr);
    
        return(cnt);
    }
    
    void __fastcall TForm8::b1Click(TObject *Sender)
    {
        AnsiString sData;
        sData = "";
    
        for(int i = 0; i < 564; i++)
        {
            sData += 'a';
        }
    
        vpf(L"%S", sData);
    }
    

    Die Funktion vpf() bildet quasi das TUnicodeString.vprintf() nach.
    Wenn in der Schleife der String um ein Zeichen kürzer ist, gibt es keine Zugriffsverletzung.

    Gibt es eventuell irgendwo die Implementierung von vsnwprintf(), bzw kann dies mal jemand mit Builder XE, XE2 testen?

    MfG Stephan



  • Zunächst mal gibts TUnicodeString nicht, sondern nur UnicodeString.

    Stephan schrieb:

    Gibt es eventuell irgendwo die Implementierung von vsnwprintf()

    $(BDS)\source\cpprtl\Source\io\vprinter.c, vprintf.c, vprintfw.c. Die Ursache findest du auch gleich in vprinter.c:

    // vprinter.c, l. 39:
    #define MAX_BUF_LEN      512
    

    Vielleicht hast du mit der Delphi-Formatierungsfunktion (Sysutils::Format()) mehr Glück; ich weiß nicht, wie es da um die Puffergröße steht. (Die Implementation kannst du in $(BDS)\source\Win32\rtl\sys\SysUtils.pas nachlesen.) Ansonsten nimm boost::format oder Streams.



  • @audacia
    Also wenn ich dies richtige verstanden habe wird dieser Buffer nur zur Konvertierung in der Funktion __vprintert() verwendet.
    Was natürlich auch erklärt warum alles funktioniert wenn ich meinen zu langen String zuerst in einen UnicodeString umwandle.

    Format() kann ich leider nicht verwenden, da ich eine Klasse fürs Loggen verwende welche seine Parameter (const wchar_t* format, ...) an UnicodeString.vprintf() weitergibt.
    Oder gibt es eine Möglichkeit die variable Argumentenliste an Format() weiterzugeben?

    Weißt Du was ich machen müßte wenn ich die Funktion __vprintert() ändern wollte?
    Also was muß neu compiliert werden, damit die geänderte Funktion dann auch von UnicodeString.vprintf() usw verwendet wird?

    MfG Stephan


Anmelden zum Antworten