Print-Adresse der virtuellen member-Funktion
Ich versuche, drucken Sie die Adresse einer virtuellen member-Funktion.
Wenn ich weiß, welcher Klasse Sie implementiert die Funktion kann ich schreiben:
print("address: %p", &A::func);
Aber ich wollen, so etwas zu tun:
A *b = new B();
printf("address: %p", &b->func);
printf("address: %p", &b->A::func);
Allerdings nicht kompilieren. Ist es möglich, so etwas zu tun, vielleicht suchen die Adresse der vtable zur Laufzeit?
InformationsquelleAutor hidayat | 2010-06-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Derzeit gibt es keine standard-Weg, dies zu tun, in C++, obwohl die Informationen verfügbar sein müssen, irgendwo. Wie sonst könnte das Programm die Funktion aufrufen? Jedoch, GCC bietet eine Erweiterung, die es uns erlaubt, um die Adresse eines virtuellen Funktion:
...vorausgesetzt die member-Funktion hat den Prototyp
void func()
.Dies kann Recht nützlich sein, wenn Sie wollen, um den cache der Adresse eines virtuellen Funktion zu nutzen oder es im generierten code. GCC warnt Sie über dieses Konstrukt, es sei denn, Sie geben
-Wno-pmf-conversions
. Es ist unwahrscheinlich, dass es funktioniert mit jedem anderen compiler.InformationsquelleAutor Lukas W
Zeiger auf member-Funktionen sind nicht immer einfachen Speicher-Adressen. Siehe die Tabelle in dieser Artikel zeigt die Größen der member-Funktion-Zeiger auf verschiedene Compiler - einige gehen bis zu 20 bytes.
Als der Artikel skizziert eine member-Funktion-Zeiger ist tatsächlich ein blob von der Implementierung definierte Daten zur Lösung eines Anrufs über den Zeiger. Sie können speichern und Sie zu rufen, OK, aber wenn Sie wollen, zu drucken, was Sie drucken? Am besten behandeln Sie es als eine Sequenz von bytes, und seine Länge über
sizeof
.virtual
nennen 🙂 ?Das war nicht Teil der Frage war es? Aber ich würde die Antwort durch den Aufruf' 🙂
InformationsquelleAutor AshleysBrain
Habe ich einen Weg gefunden, dies zu tun mit einem disassembler (https://github.com/vmt/udis86). Die Schritte sind:
Einen Zeiger auf die virtuelle Funktion über den normalen C++ - code
Zerlegen die
jmp
Instruktion an dieser AdresseParse die real-Adresse aus den zerlegten string
Hier ist, wie ich es gemacht habe:
InformationsquelleAutor Zachary Canann
Macht nicht viel Sinn für mich. Wenn Sie eine normale Funktion:
dann können Sie seine Adresse:
aber Sie können nicht die Adresse einer Funktion nennen, das ist, was Sie scheinen zu wollen, zu tun.
InformationsquelleAutor
Was ich sagen kann, in der standard, die einzige Zeit, die Sie bekommen, dynamische Bindung ist, während eine virtuelle Funktion nennen. Und sobald Sie angerufen haben, eine Funktion, die Sie ausführen, werden die Anweisungen innerhalb der Funktion (d.h., Sie können nicht "auf halbem Wege stehenbleiben" in den Anruf bekommen und die Adresse.)
Ich denke, es ist unmöglich.
InformationsquelleAutor GManNickG