Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi WINAPI-Funktionen Windows Versionsabhängig (https://www.delphipraxis.net/106947-winapi-funktionen-windows-versionsabhaengig.html)

RWarnecke 19. Jan 2008 13:33


WINAPI-Funktionen Windows Versionsabhängig
 
Hallo zusammen,

ich habe mal wieder ein Problem, ich verwende in meinem Programm SystemInfo in der neuen Version den folgenden Aufruf im Interface-Teil :
Delphi-Quellcode:
function GetAdaptersAddresses(Family: ULONG; Flags: cardinal; Reserved: PVOID;
  pAdapterAddresses: PIP_ADAPTER_ADDRESSES; pOutBufLen: PULONG): dword; stdcall;
     external 'IPHLPAPI.DLL' name 'GetAdaptersAddresses';
Wenn ich jetzt das Program unter Windows XP und höher aufrufe funktioniert alles ganz wunderbar. Nur wenn ich das Programm jetzt unter Windows 2000 aufrufe, gibt es die Fehlermeldung, das er den Einstiegspunkt nicht findet. Das ist mir ja auch klar, wie man unter MSDN-Library durchsuchenGetAdaptersAddresses nachlesen kann.

Nun zu meiner Frage, kann ich das ganze trotzdem verwenden und es zur Windowsversion abhängig machen ?

DeddyH 19. Jan 2008 13:47

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Hallo Rolf,

verwende doch dynamische statt statischer Bindung, also mit LoadLibrary und GetProcAddress ermitteln, ob die Funktion vorhanden ist. Wenn nicht, ist sie halt nicht zu verwenden, aber das Programm läuft zumindest.

RWarnecke 19. Jan 2008 13:53

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Hallo Deddy,

das wäre eine Idee, mal schauen was ich daraus machen kann.

RWarnecke 19. Jan 2008 20:47

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Habe das Problem jetzt mit LoadLibrary und GetProcAddress gelöst.

DeddyH 19. Jan 2008 20:55

Re: WINAPI-Funktionen Windows Versionsabhängig
 
:thumb:

RWarnecke 22. Jan 2008 18:32

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Ich habe dazu noch eine Frage, kann ich an dem folgenden Beispiel noch etwas optimieren/verbessern ?
Delphi-Quellcode:
hclxwin32 := LoadLibrary('clxwin32.dll');
hnetwin32 := LoadLibrary('netwin32.dll');
hcalwin32 := LoadLibrary('calwin32.dll');
if (hclxwin32 <> 0) and (hnetwin32 <> 0) and (hcalwin32 <> 0) then
begin
  @CallsInit := GetProcAddress(hcalwin32, 'NWCallsInit');
  @ScanConnRefs := GetProcAddress(hclxwin32, 'NWCCScanConnRefs');
  @GetConnRefInfo := GetProcAddress(hclxwin32, 'NWCCGetConnRefInfo');
  @OpenConnByRef := GetProcAddress(hclxwin32, 'NWCCOpenConnByRef');
  @CreateContextHandle := GetProcAddress(hnetwin32, 'NWDSCreateContextHandle');
  @MapIDToName := GetProcAddress(hnetwin32, 'NWDSMapIDToName');
  if (@CallsInit <> nil) and (@ScanConnRefs <> nil) and
     (@GetConnRefInfo <> nil) and (@OpenConnByRef <> nil) and
     (@CreateContextHandle <> nil) and (@MapIDToName <> nil) then
  begin

    // irgendwelcher Code wird abgearbeitet

  end;
end;

DeddyH 22. Jan 2008 18:35

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Wenn Sofern Du auch irgendwo FreeLibrary aufrufst, sehe ich jetzt nichts.

[edit] So wird deutlicher, was ich gemeint hatte ;) [/edit]

RWarnecke 22. Jan 2008 18:48

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Zitat:

Zitat von DeddyH
Wenn Du auch irgendwo FreeLibrary aufrufst, sehe ich jetzt nichts.

Ok, das mit FreeLibrary habe ich hier vergessen, da das nur ein Ausschnit aus der Funktion ist. FreeLibrary rufe ich ganz am Schluss der Funktion auf.

sirius 22. Jan 2008 18:51

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Woran und wo gedenkst du denn zu verbessern? Kürzerer Quellcode oder kürzere Laufzeit?
Aber ich denke kaum, dass hier sinnvoll etwas rausgeholt werden kann.

RWarnecke 22. Jan 2008 18:56

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Zitat:

Zitat von sirius
Woran und wo gedenkst du denn zu verbessern? Kürzerer Quellcode oder kürzere Laufzeit?

Ich denke hauptsächlich an die IF-Schleifen. Denn wenn ich mehrere Befehle habe, kann die ja ziemlich lang werden, was ich für nicht so gut halte. Gibt es vielleicht eine Möglichkeit mit einem Befehl mehrere Funktionen einer DLL zu überprüfen. Da möchte ich optimieren/verbessern.

DeddyH 22. Jan 2008 18:59

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Zitat:

Zitat von RWarnecke
Gibt es vielleicht eine Möglichkeit mit einem Befehl mehrere Funktionen einer DLL zu überprüfen.

Dafür kenne zumindest ich keine Möglichkeit.

BTW: Es gibt keine if-Schleifen ;)

sirius 22. Jan 2008 19:02

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Du könntest dir maximal dein eigenes GetProcAddress schreiben. Aber das fällt für mich kaum unter "sinnvoll". Da bist du so viel schneller. Oder vielleicht.... also eine WinAPI-Funktion gibt es nicht. Du müsstest, dann ja eine Liste übergeben. und eine Liste zurückbekommen.

IF-Schleifen :ouch:RoterKasten

RWarnecke 22. Jan 2008 19:03

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Zitat:

Zitat von DeddyH
BTW: Es gibt keine if-Schleifen ;)

:cyclops: Kommt davon, wenn man sich anderen Sourcecode anschaut und die Antwort schreibt.

sirius 22. Jan 2008 20:16

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Du kannst dir maximal eine Funktion bauen, dir die eine Liste füllt o.ä. (je nachdem wie flexibel du die funktionen brauchst):
Delphi-Quellcode:
function getProcList(lib:Integer;const FunctionNames:TStringlist):boolean;
var i:integer;
    addr:pointer;
begin
  result:=true;
  for i:=0 to Functionnames.count-1 do
  begin
    addr:=getprocaddress(lib,pchar(functionNames.names[i]));
    if addr=nil then
    begin
      result:=false;
      exit;
    end;
    Functionnames.ValueFromIndex[i]:=inttostr(integer(addr));
  end;
end;

RWarnecke 22. Jan 2008 20:26

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Hallo Sirius, das wäre eine Idee. Ich lasse mir die mal durch den Kopf gehen. Ich danke Dir schonmal für den Denkanstoss. :coder2:

sirius 22. Jan 2008 20:48

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Und wenn wir bei optimieren sind: Jedesmal getprocaddress neu anstoßen, bedeutet ja auch jedesmal die Tabelle mit den Exporteinträgen von vorne durchwühlen, bis die strings übereinstimmen. Da kann man natürlich auch einmal durchgehen. Hier allerdings bis zum bitteren Ende, ob das Vorteile bringt :gruebel:

Delphi-Quellcode:
function getProcList(libs:array of hModule;const FunctionNames:TStringlist):boolean;
var Exp:PImageExportDirectory;
    i,a:integer;
    name:string;
    addr:pointer;
    index:integer;
    listfilled:integer;
    lib:integer;
begin

  try

    listfilled:=0;


    for a:=0 to high(libs) do
    begin

      lib:=libs[a]; //a-te Library aus libs lesen

      if (lib=0)or
         (PWord(pointer(lib))^<>$5A4D)or
         (PImageNTHeaders(PImageDosHeader(pointer(lib))^._lfanew+lib)^.Signature<>$4550)
         then continue; //ist keine Win-DLL/EXE


      //ExportTabelle finden
      Exp:=pointer(PInteger(@PImageNTHeaders(PImageDosHeader(pointer(lib))^._lfanew+lib)^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT])^+lib);

      //alle Export-Einträge durchlaufen
      for i:=0 to exp^.NumberOfNames-1 do
      begin
        //Name der i-ten Export-Funktion
        name:=pchar(pinteger(integer(exp^.AddressOfNames)+lib+i*4)^+lib);

        //Name in Liste suchen
        index:=Functionnames.IndexOfName(name);
        if index>=0 then
        begin
          //Adresse der i-ten Export-Funktion
          addr:=pointer(pinteger(integer(exp^.AddressOffunctions)+lib+i*4)^+lib);
          //Adresse in Liste speichern
          Functionnames.ValueFromIndex[index]:=inttostr(integer(addr));

          inc(listfilled);
        end;
      end;
    end;

    result:=listfilled=Functionnames.Count;

  except
    result:=false; //was auch immer
  end;
end;



procedure TForm1.Button1Click(Sender: TObject);
var list:TStringlist;
begin
  list:=TStringlist.create;
  list.Add('CreateWindowExA=');
  list.Add('CreateWindowExW=');
  list.add('GetProcAddress=');
  if getProcList([getmodulehandle('user32.dll'),
                  getmodulehandle('kernel32.dll')],
                  list) then memo1.lines.addstrings(list);
end;

Dezipaitor 22. Jan 2008 21:39

Re: WINAPI-Funktionen Windows Versionsabhängig
 
Du kannst auch die JEDI API verwenden. Die macht, wenn dynamisch compiliert, das alles automatisch für dich. Es wird tatsächlich nur einmal geladen.
Man muss nur überprüfe, ob der Funktionspointer nicht nil ist oder einfach try/except verwenden, wenn die Fkt aufgerufen wird.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:52 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