Zitat von
DJ-SPM:
Ok, das ist alles noch etwas neu für mich. Danke für deine Erklärung. Aber was ist ein ungetypter/ungecasteter Zeiger?
Also ein Zeiger ist einfach nur eine Adresse (Pointer). Du zeigst wirklich auf eine bestimmte Adresse. Jetzt besagt der Typ Pointer, dass du, wenn du ihm folgst an einer bestimmten Stelle im Speicher landest, soweit so gut. Dummerweise weißt du jetzt nicht was sich an dieser Stelle im Speicher befindet. Da kann so ziemlich alles sein, nichts, eine Klasse, ein Record, ein Array, ein String, ein Integer,....
Natürlich machst du zu keinem Zeitpunkt etwas anderes als auf Speicher zuzugreifen, auch wenn du ein i: Integer verwendest und hier i einen neuen Wert zuweißt, wirst du irgendwo auf den Speicher zugreifen. Aber hier weiß das Programm, dass du ein Integer-Wert setzt. Damit ist die Typprüfung möglich, aber es passiert noch mehr. Du kennst die Adresse nie direkt, Delphi übernimmt das für dich. Weißt du i einen Wert zu, so wird einfach die Adresse der Variablen genommen und hier die 4 Byte (auf einer 32 Bit Maschine) als ein Integer interpretiert.
Typisierte Zeiger sind einfach Zeiger, von denen du weißt worauf sie zeigen. z.B. könntest du auf ein Integer zeigen. Dann kannst du hier nur die Adresse eines Integers zuweisen, versuchst du das gleiche mit der Adresse eines Strings, wird der Compiler das nicht zulassen.
Natürlich hat das den Vorteil, dass du so wieder eine Typprüfung hast. Greifst du auf den Wert zu, auf den der typ. Zeiger zeigt, so weiß Delphi wie dieser Wert zu interpretieren ist.
Auch Funktionen haben eine bestimmte Adresse. Was beim Aufruf einer Funktion gemacht wird ist auch wieder ganz einfach. Die Variablen werden auf eine bestimmte Art so abgelegt, dass die Funktion sie finden kann. Das wie hängt dabei von der Aufrufkonvention (z.B. Pascal, cdecl, stdcall) ab. Dann wird zu der Adresse gesprungen, an der sich der Code der Funktion befindet und diese abgearbeitet.
Während die Adressen (zumindest die virtuellen) deines Programms statisch sind, brauchst du beim dyn. Laden von Bibliotheken eine Möglichkeit die Sprungadresse erst zur Laufzeit zu ermitteln (das steckt in dem Code den du gepostet hast).
Jetzt kann eine
DLL ganz beliebige Funktionen enthalten, der Entwickler legt fest welche und was diese für Argumente erwarten. Windows liefert dir also nur die Adresse der Funktion. Dies kann nur eine allgemeine Adresse sein. Willst du jetzt die entsprechende Funktion aufrufen, muss Delphi erst wissen was sich hinter der Adresse verbirgt. Eine allgemeine Adresse kann zwar eine Funktion sein, aber eben auch ein Integer, ein String...
Deswegen castest du die Adresse und legst damit den Typ dessen fest, was sich an der Adresse befindet.
Gruß Der Unwissende