va_args und 64 bit

Ich bin der lead-dev für Bitfighter, und habe Probleme die Portierung des Spiels auf 64-bit-Linux. Dies sollte eine relativ einfache und häufiges problem, aber es hat überfragt einer Reihe von Menschen, und ich finde keine guten Informationen darüber.

[[ Der code wird kompiliert in 32-bit mit gcc version 4.1.2, und andere, und schlägt mit mehreren Varianten von 64-bit-Linux, aber ich verlasse mich auf Berichte von anderen, und nicht die genaue version von gcc, die fehlschlägt. Aber es nicht für mehrere Personen, auf einer Vielzahl von Linux-Geschmacksrichtungen. Ich bin 99% sicher, dies ist nicht eine compiler-version Problem. ]]

Habe ich Folgendes:

 void UserInterface::drawCenteredString(int y, int size, const char *format, ...)
   {
    va_list args; 
    va_start(args, format); 
    char buffer[2048]; 
    dVsprintf(buffer, sizeof(buffer), format, args); 
    va_end(args);

    drawCenteredString2(y, size, buffer);
 }   

 //Elsewhere, in platform.cpp... (this is where the error occurs)

 S32 dVsprintf(char *buffer, int bufferSize, const char *format, void *arglist)
 {
    return vsnprintf(buffer, bufferSize, format, (char *) arglist);
 }

Dies funktioniert gut auf 32-bit-Plattformen. Allerdings, wenn ich es kompilieren auf 64-bit-Linux schlägt fehl:

 platform.cpp:457: error: cannot convert 'char*' to '__va_list_tag*' for argument '4' to 'int TNL::vsnprintf(char*, size_t, const char*, __va_list_tag*)'

Habe ich versucht, viele Varianten, einschließlich:

return vsnprintf(buffer, bufferSize, format, (va_list) arglist);

ohne Erfolg.

Hat jemand irgendwelche Ideen, wie man dieses Konstrukt tragbar, oder das gleiche zu erreichen endet mit einem mehr von 64-bit-freundliche Mechanismus?

Sowie, für bonus-Punkte 🙂 kann mir jemand sagen wo die va_list_tag Dingens kommt?

Dank!

============================================

Hier ist die Lösung ließen wir uns auf, ein anderes Beispiel:

logprintf("Hello %s", name);

Anrufe

void logprintf(const char *format, ...)
{
   va_list s;    
   va_start( s, format );

   logger(LogConsumer::GeneralFilter, format, s);
   va_end(s);
}

Anrufe

void logger(LogConsumer::FilterType filtertype, const char *format, va_list args)
{
   char buffer[4096];

   vsnprintf(buffer, sizeof(buffer), format, args);

   Platform::outputDebugString(buffer);
}
  • Könnten Sie bitte Informationen hinzufügen, die angibt, welche Zeile es ist, wo der Fehler Auftritt? Im inneren Benutzeroberfläche::drawCenteredString oder innerhalb dVsprintf? Bitte auch hinzufügen, was compiler (genaue version) und welches Betriebssystem (linux), die Sie verwenden.
  • Ich veränderte die Frage zu klären, dass der Fehler Auftritt, wo dVsprintf() definiert ist.
  • auf einigen 64-bit-Implementierungen va_list ist nicht nur Zeiger auf den stack ist, wie es ist mit den üblichen x86-C Aufrufkonventionen. Dies ist, weil die ersten paar Argumente übergeben werden, die über Register.
InformationsquelleAutor Watusimoto | 2010-01-26
Schreibe einen Kommentar