Die Implementierung eines rohen Thunk im Stil von V-Table Thunks ist ein letzter Ausweg. Was immer Sie erreichen müssen, kann höchstwahrscheinlich mit einer Wrapper-Funktion erreicht werden, und es wird viel weniger schmerzhaft sein.
Im Allgemeinen ist ein Thunk führt Folgendes aus:
- die Eingangsparameter Fix up (zB umwandeln in ein anderes Format)
- Rufen Sie die reale Umsetzung
- Abgleich Schritt 1/fix die Ausgangsparameter
ein Beispiel zu sehen, wie es funktioniert, lassen sie sich zu unserem guten Freund Raymond Chen und seine Diskussion Teller Thunks drehen:
http://blogs.msdn.com/oldnewthing/archive/2004/02/06/68695.aspx
Die Thunk er war wie folgt verwendet:
[thunk]:CSample::QueryInterface`adjustor{4}':
sub DWORD PTR [esp+4], 4 ; this -= sizeof(lpVtbl)
jmp CSample::QueryInterface
Als er beschreibt, Sie haben eine Klasse, die die gleichen Methoden über mehrere Schnittstellen implementiert, so hat es mehrere V-Tabellen. (Wenn Sie COM nicht kennen, müssen Sie nur wissen, dass es direkt mit v-tables funktioniert. Daher muss ein Zeiger auf eine bestimmte Schnittstelle Funktionszeiger auf alle Methoden dieser Schnittstelle in der Reihenfolge enthalten.)
Wenn Sie zwei Schnittstellen mit unterschiedlichen Methoden in einem bestimmten Steckplatz implementieren, benötigen Sie mehrere v-Tabellen. Aber Sie schreiben die überlappenden Methoden nur einmal, so dass die Methode mit beiden "diesen" Zeigern arbeiten kann.Dazu generiert der Compiler eine Methode, die die erforderliche Korrektur durchführt und die ursprüngliche Implementierung aufruft.
Also, das Thunk führt die folgenden Schritte aus:
- die Eingangsparameter Fix, nämlich den verborgenen „diesen“ Zeiger, in der ersten Zeile.
- Rufen Sie die reale Implementierung in der zweiten Zeile auf.
- Cleanup: kein erforderlich (siehe unten)
Dies ist, wo die jmp
Anweisung kommt in der Regel, wenn Sie die Funktion call
nennen sind, es zu Ihnen zurückkommen würde, und man müßte. ret
zurück zu Ihrem Anrufer. Da keine Bereinigung zu tun ist, führt der Compiler eine Optimierung durch, bei der die Ausführung direkt auf die reale Implementierung verschoben wird. Lassen Sie die Rückgabeanweisung der realen Implementierung an Ihren Aufrufer zurücksenden. Dies ist nur eine Optimierung, kein grundlegender Teil des Thunkings. Zum Beispiel werden 16/32-Bit-Thunks die Eingabe-/Ausgabeparameter je nach Bedarf zwischen 16 und 32 Bit konvertieren, so dass der Bereinigungsschritt nicht übersprungen werden kann; es muss call
, nicht jmp
.
Die Moral der Geschichte ist: Wenn Sie etwas brauchen, wie die jmp
Optimierung zu tun, dass Sie nicht direkt in C schreiben kann ++ oder Ihre anderen High-Level-Sprache der Wahl, gehen Sie vor und schreiben thunk eine Assemblersprache . Ansonsten schreib einfach einen Wrapper und sei damit fertig.
Ehrlich gesagt, es klingt wie Sie nach der Leistungsoptimierung fragen, und die meiste Zeit (1) der Compiler ist besser zu optimieren als wir denken und (2) es wird nicht geben Sie als eine große Verbesserung wie Sie denken.
Könnten Sie bitte Ihre Frage klären? Im Moment, zusammen mit deinen Kommentaren, sieht es aus wie "erzähl mir alles über alles was Thunks betrifft", was ein bisschen ... breit ist. – peterchen