Übereinstimmende va_list-Typen zwischen Compilern

8

Ich habe ein Projekt, das aus einer Reihe dynamisch geladener Module besteht. Ursprünglich wurde alles mit MSVC 2003 erstellt, aber in letzter Zeit habe ich daran gearbeitet, es mit GCC zu arbeiten. Alles lief ziemlich reibungslos, bis auf ein Problem. Bei 64-Bit-Code stimmen GCC und MSVC nicht überein, was ein va_list ist. Für 32-Bit scheinen die Dinge in Ordnung zu sein. Das Problem der 64-Bit-Mismatch ist, wenn ein Modul, das mit einem Compiler erstellt wurde, eine öffentliche Funktion mit einem va_list -Parameter hat und diese Funktion von einem Modul aufgerufen wird, das vom anderen Compiler erstellt wurde.

Die Spezifikation sagt nichts darüber aus, was ein va_list ist, außerhalb von Abschnitt 7.15 Variable Argumente <stdarg.h> , Absatz 3:

  

Der angegebene Typ ist

     

va_list

     

Dies ist ein Objekttyp, der die von den Makros benötigten Informationen enthält va_start , va_arg , va_end und va_copy .

Dieser Absatz bedeutet nur, dass dies alles Compiler-abhängige Dinge sind - gibt es also eine Möglichkeit, diese beiden Compiler auf den Inhalt eines 64-Bit va_list abzustimmen? Für die geringste Auswirkung auf mein System wäre GCC am besten mit der MSVC va_list kompatibel, aber ich nehme jede Lösung, die ich bekommen kann.

Danke, dass Sie mithelfen!

Bearbeiten:

Ich habe einige 32-Bit-Tests gemacht, und ich habe auch Probleme, die mich überrascht haben, da es angeblich keine ABI-Unterschiede zwischen 32-Bit-Intel-Plattformen gibt. Die MSVC-Codebasis, die ich verwende, definiert alle variadischen Funktionsmakros wie folgt:

%Vor%

Ich habe ein bisschen vom realen Projekt vereinfacht, aber das ist der Code, den ich für meinen Test verwendet habe. Mit GCC erhält dieser Code meine Argumente definitiv nicht richtig. Vielleicht ist es nur ein Fehler, wie Zack unten vorschlägt?

Nochmals bearbeiten:

Ich erhalte Arbeitsergebnisse für die folgende 32-Bit-Testanwendung mit -O0 , -O0 und -O2 , aber nicht -O3 , -Os und -Oz :

%Vor%     
Carl Norum 29.09.2010, 18:31
quelle

5 Antworten

5

Da MSVC den Win64 ABI definiert, haben Sie einen Fehler in GCC gefunden. Bitte melden Sie es in GCC bugzilla .

    
zwol 29.09.2010, 19:06
quelle
2

Da es anscheinend keinen ABI für va_list gibt (oder zumindest MSVC und GCC nicht mit einem ABI einverstanden sind), müssen Sie diese Parameter wahrscheinlich selbst marshallen.

Die einfachste Möglichkeit, um dieses Problem von oben zu lösen, besteht darin, Ihre variablen Parameter in einem dynamisch zugewiesenen Speicherblock zu verwalten und einen Zeiger auf diesen Block zu übergeben.

Das hat natürlich den Nachteil, dass die Schnittstelle zu den Funktionen, die va_args verwenden, komplett geändert wurde.

    
Michael Burr 29.09.2010 18:50
quelle
0

Da es keinen Standard gibt, wie va_args gehandhabt werden müssen, sollten Sie Ihre eigene Version wahrscheinlich besser rollen lassen, wenn Sie diese Funktionalität in einer kompilierten Plattform konsistent nutzen möchten. Wir haben dies nicht getan und wurden in letzter Zeit mehrmals gebrannt, als wir zusätzliche Ziele für unsere Codebasis unterstützten. Ich würde gerne falsch liegen, wenn andere eine bessere Lösung haben:)

    
Michael Dorgan 29.09.2010 18:39
quelle
0

Versuchen Sie es mit einem Debugger auf Assembly-Ebene wie ollydbg auszuführen, da Ihr Problem möglicherweise nicht mit den va_args zusammenhängt, sondern mit der Art, wie der Compiler die Argumente erwartet (gcc könnte sie im linux-Format erwarten), wo msvc win64 __fastcall verwendet), wird dies der Situation etwas mehr Licht geben. Ein anderer, ziemlich hacky Ansatz ist versuchen, mit den Definitionen für die 64-Bit-Argumente, wie Importieren der MSVC-Makros in den GCC-Header (verwenden Sie eine Projekt lokale Kopie natürlich), sehen, ob das etwas heilt.

    
Necrolis 29.09.2010 18:49
quelle
-1

Welche Arten verwenden Sie? Streng genommen definiert WinXX nur das Verhalten von Zeichen, Strings, Zeigern und ganzen Zahlen für Varargs ( siehe Dokumentation für wsprintf in user32.dll ). Wenn Sie Fließkommawerte oder Strukturen übergeben, sind die Ergebnisse für die Windows-Plattform technisch nicht spezifiziert.

    
MSN 29.09.2010 19:43
quelle