Einzelnen Beitrag anzeigen

Benutzerbild von JamesTKirk
JamesTKirk

Registriert seit: 9. Sep 2004
Ort: München
604 Beiträge
 
FreePascal / Lazarus
 
#17

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde

  Alt 12. Mär 2010, 20:23
So... *Ärmel hochkrempelt*

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
  var
  DLLHandle,hProcessSnap: THandle;
  Beispielfunktion: function(dwFlags:Integer;th32ProcessID:Integer):THandle;//alternativ Funktionsergebnistyp:Pointer, mit dem klappt es aber auch nicht
begin
  DLLHandle := LoadLibrary(kernel32);
  if (DLLHandle < HINSTANCE_ERROR) then showmessage('DLL konnte nicht geladen werden!')
  else
    begin
    Beispielfunktion := @GetProcAddress(DLLHandle, 'CreateToolhelp32Snapshot');//klappt auch nicht, wenn ich das „@“ weglasse
    //hProcessSnap:=CreateToolHelp32SnapShot(2{TH32CS_SNAPPROCESS},0);

    FreeLibrary(kernel32)
    end
end;
Ich erkläre dir mal die Ursache im ObjFPC-Modus:
Das Problem ist hier, dass du der Variable "Beispielfunktion" einen Verweis auf die GetProcAddress-Funktion übergibst, welche sich natürlich unterscheiden. Richtig wäre hier folgendes:

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
type
  // wir benötigen einen Typ, zu dem wir casten können
  TCreateToolhelp32SnapshotProc = function(dwFlags: Integer; th32ProcessID: Integer): THandle; stdcall; // vergiss hier das stdcall nicht!
var
  DLLHandle,hProcessSnap: THandle;
  Beispielfunktion: TCreateToolhelp32SnapshotProc;
begin
  DLLHandle := LoadLibrary(kernel32);
  if (DLLHandle < HINSTANCE_ERROR) then showmessage('DLL konnte nicht geladen werden!')
  else
    begin
    // hier müssen wir jetzt auf den korrekten Typ casten
    Beispielfunktion := TCreateToolhelp32SnapshotProc(GetProcAddress(DLLHandle, 'CreateToolhelp32Snapshot'));
    //hProcessSnap:=CreateToolHelp32SnapShot(2{TH32CS_SNAPPROCESS},0);
    // aufrufen würdest du sie jetzt so:
    hProcessSnap := Beispielfunktion(2, 0);

    FreeLibrary(kernel32)
    end
end;
Ich weiß jetzt allerdings nicht aus dem Stegreif, ob der Code so dann auch unter Delphi funktioniert.

Du hast folgenden Code als Beispiel gepostet:
Delphi-Quellcode:
interface

function OpenThread(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; stdcall;

implementation

function OpenThread; external kernel32 name 'OpenThread';
Das Problem hier ist, das dies in meinen Augen eine Unsauberkeit des Delphi-Compilers ist. Dies sehen auch die Entwickler von Free Pascal so, weswegen sie dies nur im Delphi-kompatiblen Modus erlauben. Sowohl unter Delphi, als auch unter FPC (egal ob Modus ObjFPC oder Delphi) funktioniert folgender Code:

Delphi-Quellcode:
interface

function OpenThread(dwDesiredAccess: DWORD; bInheritedHandle: BOOl; dwProcessId: DWORD): THandle; stdcall; external kernel32 name 'OpenThread';

implementation
Hier stehen beide Angaben im Interface, was meiner Ansicht nach auch sauberer aussieht.

Und jetzt noch ein Tip am Rande: Unter Free Pascal findet sich die CreateToolHelp32SnapShot Funktion in der Unit jwatlhelp32.pas, die sich im Ordner %FPCDIR%\packages\winunits-jedi\src befindet (wobei %FPCDIR% z. B. "C:\lazarus\fpc\2.2.4" sein kann). Du brauchst den Pfad allerdings nicht mit angeben, da die Units in den Unterverzeichnissen von Packages alle in der Konfiguration von Free Pascal eingetragen sind (insofern sie für die jeweilige Plattform kompiliert wurden).
Allgemein finden sich - meines Wissens - fast alle WinAPI Funktionen in winunits-jedi. Ein Teil davon bzw die übrigen sind dann in packages/winunits-base oder rtl/win zu finden.

Gruß,
Sven
Sven
[Free Pascal Compiler Entwickler]
this post is printed on 100% recycled electrons
  Mit Zitat antworten Zitat