AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Windows API Übersetzung - Welche Variante ist besser ?
Thema durchsuchen
Ansicht
Themen-Optionen

Windows API Übersetzung - Welche Variante ist besser ?

Ein Thema von RWarnecke · begonnen am 5. Nov 2009 · letzter Beitrag vom 14. Nov 2009
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#1

Windows API Übersetzung - Welche Variante ist besser ?

  Alt 5. Nov 2009, 22:14
Hallo zusammen,

ich habe da mal eine vielleicht einfache Frage. Ich kann ja die API-Befehle von Windows in zwei Varianten nutzen. Welche der beiden Varianten ist besser geeignet, um Fehler vorzubeugen ?

Variante 1 :
Delphi-Quellcode:
  TGetAdapterAdresses = function (Family: ULONG; Flags: cardinal; Reserved: PVOID;
     pAdapterAddresses: PIP_ADAPTER_ADDRESSES; pOutBufLen: PULONG): dword; stdcall;
Variante 2 :
Delphi-Quellcode:
  function GetAdapterAdresses(Family: ULONG; Flags: cardinal; Reserved: PVOID;
     pAdapterAddresses: PIP_ADAPTER_ADDRESSES; pOutBufLen: PULONG) : DWORD; stdcall;
     external 'IPHLPAPI.DLLname 'GetAdapterAdresses';
Diese Funktion ist lediglich nur ein Beispiel. Welche Variante ist einfacher zu benutzen, um zum Beispiel den Fehler vorzubeugen, dass die IPHLPAPI.DLL nicht gefunden wird, wie in diesem Beispiel. Oder anderst gefragt, wo und wie ist es besser abzufragen, ob die dazugehörige DLL für die API-funktion vorhanden ist ?
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Windows API Übersetzung - Welche Variante ist besser ?

  Alt 5. Nov 2009, 22:23
Bei der ersten Variante definierst du nur einen Typ. Später im Programmfluss musst du dir eine Variable eben dieses Typs definieren und die Funktion selbst aus der DLL (LoadLibraryA()/GetModuleHandleA() & GetProcAddress()) laden.

Bei der zweiten Variante wird es in die Importier-Liste beim Kompilieren hineinverlinkt. Dh. der PE-Loader von Windows ist zuständig, dass er beim Initialisieren der Echse - falls diese ausgeführt wird - alle Module (DLLs) & Funktionen der Importier-Liste ladet (und weitere Aufgaben durchführt...).

MfG
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG
  Mit Zitat antworten Zitat
Benutzerbild von mirage228
mirage228

Registriert seit: 23. Mär 2003
Ort: Münster
3.750 Beiträge
 
Delphi 2010 Professional
 
#3

Re: Windows API Übersetzung - Welche Variante ist besser ?

  Alt 5. Nov 2009, 22:25
Also am einfachsten ist es im Vorfeld abzuklären, ab welcher Windows/IE Version diese Datei enthalten ist, um dann zu schauen, ob du ältere Versionen unterstützen willst.

Lädst du statisch (zweite Variante) haut dir Windows beim Start direkt eine Meldung um die Ohren, falls die DLL fehlt, diese Variante ist aber recht komfortabel. Wenn Du den ersten Punkt von mir beachtet, könntest Du ohne Bedenken diese Variante nutzen.

Für Variante 1 würde sich der "initialization" Abschnitt anbieten. Kannst Dir ja anschauen, wie Borland das macht in der VCL (Ich glaube "GetLayeredWindowAttributes" ist so ein Kandidat). Hier kannst Du natürlich ein eigenes Fehlerhandling ansetzen, hast aber mehr Aufwand.

Viele Grüße
David F.

May the source be with you, stranger.
PHP Inspection Unit (Delphi-Unit zum Analysieren von PHP Code)
  Mit Zitat antworten Zitat
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#4

Re: Windows API Übersetzung - Welche Variante ist besser ?

  Alt 5. Nov 2009, 22:28
Ok, soweit verstanden. Für Variante 1 kenne ich die vorgehensweise mit LoadLibary/GetProcAddress u.s.w. Verstehe ich das dann richtig, dass ichbei Variante 2 nur über die Windows Version gehen kann ? Oder gibt es da auch noch eine andere Möglichkeit ?
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat
Benutzerbild von mirage228
mirage228

Registriert seit: 23. Mär 2003
Ort: Münster
3.750 Beiträge
 
Delphi 2010 Professional
 
#5

Re: Windows API Übersetzung - Welche Variante ist besser ?

  Alt 5. Nov 2009, 22:31
Zitat von RWarnecke:
Ok, soweit verstanden. Für Variante 1 kenne ich die vorgehensweise mit LoadLibary/GetProcAddress u.s.w. Verstehe ich das dann richtig, dass ichbei Variante 2 nur über die Windows Version gehen kann ? Oder gibt es da auch noch eine andere Möglichkeit ?
Bei Variante 2 ist mit der Windows Version dachte ich eher an eine informelle Regelung. Du legst einfach als Systemanforderung Windows XY fest, ggf. ein Installationsprogramm könnte diese Prüfung dann vornehmen. Afaik gibt es dann keine weitere Kontrollmöglichkeit seitens deines Programmes aus (bei Variante 2), da das Prorgamm gar nicht erst gestartet wird.
Edit: Für Variante 1: Genau LoadLibrary / GetProcAddres ... für ältere Versionen von Windows wäre zu überlegen, ob Du das Programm mit einer eigenen Fehlermeldung wieder schließt, eine Dummy-Funktion schreibst, die immer "FALSE" (oder ein vergleichbares Ergebnis, das für den Fehlschlag der API Funktion steht) zurückgibt oder die Funktion selber für ältere Versionen implementierst, usw. ...
David F.

May the source be with you, stranger.
PHP Inspection Unit (Delphi-Unit zum Analysieren von PHP Code)
  Mit Zitat antworten Zitat
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#6

Re: Windows API Übersetzung - Welche Variante ist besser ?

  Alt 5. Nov 2009, 22:33
Ok, danke für die Infos. Damit kann ich was anfangen. Dann werde ich meine Unit nach Variante 1 umschreiben, da ich doch viele Funktionen habe, die über verschiedene Windows Versionen verteilt sind.

Edit: Ich unterstütze eh nur noch ab Windows 2000 oder höher. Auf ältere Versionen gehe ich schon garnicht mehr ein. Aber trotzdem habe ich ja noch unterschiede bei den API-Befehlen von Windows 2000 bis Windows 7.

Edit 2: Dabei stellt sich mir die Frage, ob ich das ganze LoadLibray/GetProcAddress nicht über eine Funktion laufen lasse. Was haltet Ihr davon ?
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat
uoeb7gp
(Gast)

n/a Beiträge
 
#7

Re: Windows API Übersetzung - Welche Variante ist besser ?

  Alt 6. Nov 2009, 00:34
RWarnecke hat folgendes geschrieben:
Dann werde ich meine Unit nach Variante 1 umschreiben, da ich doch viele Funktionen habe,
die über verschiedene Windows Versionen verteilt sind.

Variante1 ist statisch, da bekommst wenn was nichgt gefunden wird, böse Fehlermeldungen.

Versuchs mal mit folgendem (Types must aus der IPHLPAPI ziehen).

type
TGetAdapterAdresses = function(Family: ULONG; Flags: cardinal;
Reserved: PVOID; pAdapterAddresses: PIP_ADAPTER_ADDRESSES;
pOutBufLen: PULONG) : DWORD; stdcall;

function SafeLoadLibrary(const Filename: String; ErrorMode: UINT): HMODULE;
var
SaveErrorMode: UINT;
SaveFPUControlWord: Word;
begin
SaveErrorMode := SetErrorMode(ErrorMode);
try
asm FNSTCW SaveFPUControlWord end;
try
Result := LoadLibrary(PChar(Filename));
finally
asm
FNCLEX
FLDCW SaveFPUControlWord
end;
end;
finally
SetErrorMode(SaveErrorMode);
end;
end;


function GetAdapterAdresses(Family: ULONG; Flags: cardinal; Reserved: PVOID;
pAdapterAddresses: PIP_ADAPTER_ADDRESSES; pOutBufLen: PULONG) : DWORD;
var
DLLProc: TGetAdapterAdresses;
DLLHandle: THandle;
begin
result := 0;
try
DLLHandle := SafeLoadLibrary('IPHLPAPI.DLL', SEM_NOOPENFILEERRORBOX);
if DLLHandle <> 0 then begin
try
@DLLProc := GetProcAddress(DLLHandle, 'GetAdapterAdresses');
if @DLLProc <> nil
result := DLLProc(Family, Flags, Reserved, pAdapterAddresses, pOutBufLen);
finally
FreeLibrary(DLLHandle);
end;
end;
except
result := DWORD(-1);
end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#8

Re: Windows API Übersetzung - Welche Variante ist besser ?

  Alt 6. Nov 2009, 04:44
Zitat von uoeb7gp:
... Variante1 ist statisch, da bekommst wenn was nichgt gefunden wird, böse Fehlermeldungen. ...
Wenn ich bei Variante 1 mit LoadLibrary und GetProcAddress es vorher Abfrage, kann ich doch die ganzen bösen Fehlrmeldungen abfangen. Oder sehe ich das falsch ?

Zitat von uoeb7gp:
Versuchs mal mit folgendem (Types must aus der IPHLPAPI ziehen).

Delphi-Quellcode:
type
  TGetAdapterAdresses = function(Family: ULONG; Flags: cardinal;
    Reserved: PVOID; pAdapterAddresses: PIP_ADAPTER_ADDRESSES;
    pOutBufLen: PULONG) : DWORD; stdcall;

function SafeLoadLibrary(const Filename: String; ErrorMode: UINT): HMODULE;
var
  SaveErrorMode: UINT;
  SaveFPUControlWord: Word;
begin
  SaveErrorMode := SetErrorMode(ErrorMode);
  try
    asm FNSTCW SaveFPUControlWord end;
    try
      Result := LoadLibrary(PChar(Filename));
    finally
      asm
        FNCLEX
        FLDCW SaveFPUControlWord
      end;
    end;
  finally
    SetErrorMode(SaveErrorMode);
  end;
end;


function GetAdapterAdresses(Family: ULONG; Flags: cardinal; Reserved: PVOID;
  pAdapterAddresses: PIP_ADAPTER_ADDRESSES; pOutBufLen: PULONG) : DWORD;
var
  DLLProc: TGetAdapterAdresses;
  DLLHandle: THandle;
begin
  result := 0;
  try
    DLLHandle := SafeLoadLibrary('IPHLPAPI.DLL', SEM_NOOPENFILEERRORBOX);
    if DLLHandle <> 0 then begin
      try
        @DLLProc := GetProcAddress(DLLHandle, 'GetAdapterAdresses');
        if @DLLProc <> nil
          result := DLLProc(Family, Flags, Reserved, pAdapterAddresses, pOutBufLen);
      finally
        FreeLibrary(DLLHandle);
      end;
    end;
  except
    result := DWORD(-1);
  end;
end;
Danke für das Beispiel. Nur verstehe ich noch nicht, warum muss ich jetzt nochmal selber eine Funktion für die API-Funktion schreiben ? Ich wollte ja nur lediglich den Teil mit LoadLibrary und GetProcAddress in eine Funktion setzen.
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#9

Re: Windows API Übersetzung - Welche Variante ist besser ?

  Alt 6. Nov 2009, 07:39
Schau dir mal an wie es im Jedi Win32API-Projekt gemacht ist.

Solltest du D2010 oder neuer haben so wäre auch Delay Load etwas was mit dem neuen Schlüsselwort delayed ermöglicht wird.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#10

Re: Windows API Übersetzung - Welche Variante ist besser ?

  Alt 6. Nov 2009, 07:57
Zitat von Bernhard Geyer:
Schau dir mal an wie es im Jedi Win32API-Projekt gemacht ist.
Welches der Projekte meinst Du da genau ? JCL/JVCL oder welches ?
Zitat von Bernhard Geyer:
Solltest du D2010 oder neuer haben so wäre auch Delay Load etwas was mit dem neuen Schlüsselwort delayed ermöglicht wird.
Ich benutze Delphi 2006, eventuell noch 2007.
Ich verstehe nur noch nicht das Beispiel was mir uoeb7gp hier gepostet hat. Im Moment würde ich folgendermaßen vorgehen :
Delphi-Quellcode:
type
  TGetAdapterAdresses = function(Family: ULONG; Flags: cardinal;
    Reserved: PVOID; pAdapterAddresses: PIP_ADAPTER_ADDRESSES;
    pOutBufLen: PULONG) : DWORD; stdcall;

{...}

function xy(Test:string):string;
var
  AdaptersAddresses : TGetAdapaterAddresses;
  hdll : THandle;
begin
  hdll := LoadLibrary('IPHLPAPI.DLL');
  if hdll <> 0 then
  begin
    @AdapaterAddresses := GetProcAddress(hdll, 'GetAdaptersAddresses');
    if @AdaptersAddresses <> nil then
    begin
      { hier der Aufruf der Funktion und Verarbeiten der ausgelesenen Daten }
    end;
  end;
end;
Jetzt stellt sich mir die Frage, wo ist der Unterschied zwischen meinem Beispiel und dem von user]uoeb7gp[/user] ?
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:42 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz