C-structs und Vererbung?!

  • Themenstarter Themenstarter canfänger
  • Beginndatum Beginndatum
Beim Aufrufen einer Funktion werden immer als erstes die Parameter auf den Stack gepusht; diese Arbeit erledigt stets das aufrufende Programm. Das gilt auch für das Zurückliefern des Funktionsaufrufes, der durch das aufrufende Programm vom Stack gepopt wird.
Das stimmt nicht uneingeschränkt. Es gibt eine Vielzahl von Aufrufkonventionen. Bei einigen muss der aufrufende Programmteil den Stack aufräumen, bei anderen erledigt das das aufgerufene Unterprogramm. Auch müssen Parameter nicht immer über den Stack übergeben werden, man kann dazu z.B. auch die CPU-Register verwenden. Die meisten Compiler für die x86-Architektur übergeben den Rückgabewert einer Funktion beispielsweise über das EAX-Register.

Der Zeiger verseist im wesentlichen auf die Informationen, wie diese Funktion aufzurufen ist, ob über ein zu ladendes Modul oder, bei selbst geschriebenen Funktionen, direkt in den Code des laufenden Programms.
Nein. Wie die Funktion aufzurufen ist, bestimmt schon der Zeigertyp. Der Zeiger verweist lediglich auf den Einsprungspunkt der Funktion.

Deswegen ist der Ablauf beim Aufruf einer Funktion immer der gleiche, egal, ob du die Funktion über einen Funktionszeiger oder über den 'Original'-Namen aufrufst; eine zusätzliche Dereferenzierung findet nicht statt.
Doch, bei Funktionszeigern findet im Allgemeinen eine zusätzliche Dereferenzierung statt. Eine normaler Funktionsaufruf (ohne Funktionszeiger) entspricht einem Sprung an eine feste Adresse im Speicherbereich des Programms. Diese ermittelt der Linker zur Kompilierzeit und trägt sie an den entsprechenden Stellen ein. Dagegen steht die Adresse, auf die ein Funktionszeiger verweist, erst zur Laufzeit fest. Das Programm muss also zuerst diese Adresse auslesen und kann erst dann den Sprung ausführen.

Grüße,
Matthias
 
Wer den Stack aufräumt, ist letzlich egal; es ist eine Arbeit, die in jedem Fall gemacht werden muss. Allerdings denke ich, dass die aufgerufene Funktion immer einen gewissen Teil selber machen muss, da nur sie weiß, wie viele auto-Variablen sie angelegt hat.
Der Zeiger verweist lediglich auf den Einsprungspunkt der Funktion, das ist richtig. Aber bei Funktionen, die nicht statisch gebunden wurden, weil sie z.B. in einer DLL sind, verweist der Funktionszeiger auf einen Stub, der dafür sorgt, dass diese DLL auch geladen und ausgeführt wird. Aber das ist für die eigentliche Thematik irrelevant.
Ich sehe ein, dass eine zusätzliche Dereferenzierung notwendig ist. Aber darüber hinaus entsteht wohl kein zusätzlicher Aufwand. Zudem ist die Dereferenzierung eine schnelle Operation, die auf die Laufzeit eines Programms kaum Auswirkung hat.
 
Wer den Stack aufräumt, ist letzlich egal; es ist eine Arbeit, die in jedem Fall gemacht werden muss. Allerdings denke ich, dass die aufgerufene Funktion immer einen gewissen Teil selber machen muss, da nur sie weiß, wie viele auto-Variablen sie angelegt hat.
Klar. Ich wollte nur aufzeigen, dass es unterschiedliche Aufrufkonventionen gibt.

Der Zeiger verweist lediglich auf den Einsprungspunkt der Funktion, das ist richtig. Aber bei Funktionen, die nicht statisch gebunden wurden, weil sie z.B. in einer DLL sind, verweist der Funktionszeiger auf einen Stub, der dafür sorgt, dass diese DLL auch geladen und ausgeführt wird.
Auch das ist wieder nicht die ganze Wahrheit. Du beschreibst hier das verzögerte Laden von DLLs. Das ist aber nicht die einzige Möglichkeit, DLLs zu verwenden. Im Regelfall werden DLLs schon beim Programmstart geladen und die Adressen der Einstiegspunkte der DLL-Funktionen in die Import-Adresstabelle (IAT) eingetragen. Beim Aufruf einer DLL-Funktion wird dann an die entsprechende Stelle in der IAT gesprungen. Dort ist ein Sprungbefehl an die vom Lader eingetragene Adresse enthalten, welcher als nächstes ausgeführt wird. Man kann die DLL außerdem noch „per Hand“ laden (LoadLibrary) und sich die Einstiegspunkte holen (GetProcAddress) – beim „automatischen“ verzögerten Laden geschieht das genauso.

Aber wie du schon sagtest:
Aber das ist für die eigentliche Thematik irrelevant.
;-)

Grüße,
Matthias
 
Zurück