Bitte helfen Sie! Ich brauche diese Konvertierung, um Wrapper für einige C-Header für Delphi zu schreiben.
Als ein Beispiel:
%Vor%Wie kann ich "array of const" in "varargs" umwandeln?
bearbeiten : Funktion PushString befindet sich tatsächlich im Datensatz (ich habe ein vereinfachtes Beispiel angegeben), und ich habe keinen direkten Zugriff auf den Pushstring. Direkter Anruf ist ausgeschlossen.
edit 2 : Ich schreibe die Einheiten für LUA-Bibliothek für Delphi und der Fall ist ziemlich wichtig für mich.
Angabe und Bereitstellung aller Details der Sache - Ich habe diese Funktion in C:
%Vor%In Delphi habe ich so etwas:
LuaLibrary.pas
%Vor%dtxLua.pas
%Vor%und in anderen Einheiten wie Lua.pas verwende ich nur TLuaState von dtxLua.pas (weil LuaLibrary sperrig ist, dtxLua ist mein Wrapper), für viele nützliche und coole Dinge ...
Ich vermute, dass der Prototyp für pushfstring
etwa so aussieht:
Wenn nicht und stattdessen:
%Vor%... dann sollte ich dich auch abdecken.
Wenn Sie in C einen Anruf von einer Variadic-Funktion an eine andere weitergeben müssen, sollten Sie va_list
, va_start
und va_end
verwenden und die v
-Funktion der Funktion aufrufen. Wenn Sie also printf
selbst implementiert haben, könnten Sie vsprintf
verwenden, um die Zeichenfolge zu formatieren - Sie können sprintf
nicht direkt aufrufen und die Variadic-Argumentliste weiterleiten. Sie müssen va_list
und Freunde verwenden.
Es ist ziemlich umständlich, C's va_list
von Delphi zu behandeln, und technisch sollte es nicht gemacht werden - die Implementierung von va_list
ist spezifisch für die Laufzeit des C-Compiler-Herstellers.
Aber wir können es versuchen. Angenommen, wir haben eine kleine Klasse - obwohl ich es zu einem Rekord für die Benutzerfreundlichkeit gemacht habe:
%Vor%Mit diesem Datensatz können wir den Call-Frame manuell erstellen, der für verschiedene C-Aufrufe erwartet wird. Die Aufrufkonvention von c auf x86 besteht darin, Argumente von rechts nach links auf dem Stapel zu übergeben, wobei der Aufrufer aufräumt. Hier ist das Skelett einer generischen C-Aufrufroutine:
%Vor% Nehmen Sie printf
als Beispiel:
Der Aufruf der va_list
Version ist etwas komplizierter, da der Speicherort des va_list
Arguments genau dort platziert werden muss, wo es erwartet wird:
Anmerkungen:
Das obige erwartet x86 unter Windows. Microsoft C, bcc32 (Embarcadero C ++) und gcc übergeben va_list
auf die gleiche Weise (ein Zeiger auf das erste variadische Argument auf dem Stapel), entsprechend meinen Experimenten, also sollte es für Sie arbeiten; aber sobald die x86 unter Windows-Annahme kaputt ist, erwarte, dass dies möglicherweise auch bricht.
Der Stapel wird getauscht, um die Konstruktion zu vereinfachen. Dies kann mit mehr Arbeit vermieden werden, aber das Übergeben von va_list
wird auch schwieriger, da es auf die Argumente zeigen muss, als ob sie auf dem Stapel übergeben würden. Als eine Konsequenz muss der Code eine Annahme darüber machen, wie viel Stapel die aufgerufene Routine verwendet; In diesem Beispiel wird 8K angenommen, dies ist jedoch möglicherweise zu klein. Erhöhen Sie bei Bedarf.
Der Wrapper, den Sie schreiben wollen, ist in Free Pascal möglich, da Free Pascal zwei gleichwertige Deklarationen für externe Funktionen unterstützt:
also statt
%Vor%Sie sollten
schreiben %Vor%Update: Ich habe den gleichen Trick in Delphi versucht, aber es funktioniert nicht:
%Vor%Ein "Array von const" ist eigentlich ein Array von TVarRec, welches eine spezielle Variante ist. Es ist nicht kompatibel mit Varargs, und Sie sollten in der Lage sein, die varargs-Funktion direkt ohne Wrapper aufzurufen.
Tags und Links arrays delphi variadic-functions