Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Bedingt Prozedur aufrufen (https://www.delphipraxis.net/107213-bedingt-prozedur-aufrufen.html)

CRoSSi 24. Jan 2008 09:45

Re: Bedingt Prozedur aufrufen
 
Meine mit geladen:
Delphi-Quellcode:
procedure PortOut(Port : Word; Data : Byte);stdcall; external 'io.dll';
Aber wie funktioniert das Dyamisch? Habe das noch nicht ganz so kappiert..wie es in dem einen thread (s.o.) beschrieben ist.
Evtl kann man mir jemand nen gutes beispiel machen?

Thx nochmal

DeddyH 24. Jan 2008 09:48

Re: Bedingt Prozedur aufrufen
 
Zitat aus Ollis Tut:
Zitat:

Beispiel: Dynamischer Import von DLL-Funktionen
Der dynamische Import funktioniert, wie schon gesagt, über das Holen der Adresse der zu
importierenden Funktion durch den Aufrufer.
Zuallererst muß der Aufrufer aber auch die Syntax der Funktion bekannt gemacht bekommen. Auch
wenn ein Funktionsaufruf „untendrunter“ quasi nur ein Sprung an eine bestimmte Adresse ist, kann
man ja in seinem Programm nicht wild an irgendeine Adresse springen lassen – wie sollen da die
Parameter übergeben werden? Es muß also ein sogenannter Funktionsprototyp her. In C(++) sind
die Funktionsprototypen meist in einer Header-Datei19 aufgeführt. Dies ist auch der Grund warum
diese vorher nach Delphi (ObjectPascal) übersetzt werden müssen (siehe Appendix A). Ähnlich wie
in C(++) ist die Funktionsprototypen-Deklaration in Delphi auch nur eine normale Typendeklaration:
Delphi-Quellcode:
type
TFNOneFunction = function(param1, param2, param3: Cardinal): integer;
TFNOneFunction_CDECL = function(param1, param2, param3: Cardinal): integer;
cdecl;
TFNOneFunction_STDCALL = function(param1, param2, param3: Cardinal): integer;
stdcall;
TFN ist übrigens in Delphi eine offiziell anerkannte Notation20 für Funktionstypen.
Da wir die Typen deklariert haben, brauchen wir nun noch die entsprechenden Variablen:
Delphi-Quellcode:
var
OneFunction: TFNOneFunction = nil;
OneFunction_CDECL: TFNOneFunction_CDECL = nil;
OneFunction_STDCALL_: TFNOneFunction_STDCALL = nil;
Die Variablen müssen global deklariert sein um sie mit nil initialisieren zu können, denn Delphi
erlaubt das Vorinitialisieren von Variablen nur im globalen Kontext. Nun müssen wir uns in einer, ich
schlage vor getrennten Funktion, die Adressen oder sogenannten Eintrittspunkte der Funktionen
holen:
Delphi-Quellcode:
Procedure GetEntryPoints;
var
lib:THandle;
begin
lib := LoadLibrary(@szNameDLL[1]);
case lib = 0 of
TRUE:
begin
@OneFunction_CDECL := @whatifnoentry;
@OneFunction := @whatifnoentry;
@OneFunction_STDCALL_ := @whatifnoentry;
messagebox(0, @dll_notloaded[1], nil, 0);
end;
else
begin
@OneFunction := GetProcAddress(lib, @szNameOneFunction[1]);
if not Assigned(OneFunction) then @OneFunction := @whatifnoentry;
@OneFunction_CDECL := GetProcAddress(lib, @szNameOneFunction_CDECL[1]);
if not Assigned(OneFunction_CDECL) then @OneFunction_CDECL :=
@whatifnoentry;
@OneFunction_STDCALL_ := GetProcAddress(lib, @szNameOneFunction_STDCALL[1]);
if not Assigned(OneFunction_STDCALL_) then @OneFunction_STDCALL_ :=
@whatifnoentry;
end;
end;
Man kann das Handle durch einen Aufruf von FreeLibrary() freigeben. Dies wird aber auch von
Windows erledigt, wenn der Prozeß beendet wird.

CRoSSi 24. Jan 2008 09:58

Re: Bedingt Prozedur aufrufen
 
Muss mich da wohl mal reinarbeiten.. Komme damit gerade nicht klar.. Mache das zum erstenmal mit dll's. evtl kann mir ja jemand nen Beispiel auf mich zugeschnitten machen dass ich das mal sehe. weil mit dem tutorial komme ich noch nicht so zurecht. evtl hilft mir dass Beispiel dann weiter.. und ich verstehe das tutorial richtig.

Thx nochmal für die ganzen antworten schon.

DeddyH 24. Jan 2008 09:59

Re: Bedingt Prozedur aufrufen
 
Du könntest das im Prinzip so machen:
Delphi-Quellcode:
type TPortOut = procedure(Port : Word; Data : Byte);stdcall;

...

var
  MyPortOut: TPortOut = nil;

...

var aHandle: THandle;
begin
  if var = 1 then
    begin
      aHandle := LoadLibrary('io.dll');
      if aHandle <> 0 then
      try
        @MyPortOut := GetProcAddress(aHandle,'PortOut');
        if Assigned(MyPortOut) then
          MyPortOut(aWord,aData);
      finally
        FreeLibrary(aHandle);
      end;
    end;
end;
Getippt und nicht getestet.

CRoSSi 24. Jan 2008 10:12

Re: Bedingt Prozedur aufrufen
 
So habe das mal probiert..geht leider nicht. Habe
Delphi-Quellcode:
TPortOut = procedure(Port : Word; Data : Byte);stdcall;
bei type angeben aber er sagt: BEZEICHNER ERWARTET ABER PROCEDURE GEFUNDEN

Wenn alles soweit läuft kann ich die Prozedur dann ganz normal aufrufen mit PORTOUT(..)?

DeddyH 24. Jan 2008 10:19

Re: Bedingt Prozedur aufrufen
 
Komisch, bei mir geht das. Und zum Ausführen schau Dir mein Beispiel noch einmal an. Ich versuche, die Adresse der Prozedur in der DLL zu finden und führe sie falls gefunden aus.
Delphi-Quellcode:
if Assigned(MyPortOut) then
  MyPortOut(aWord,aData);

RavenIV 24. Jan 2008 10:22

Re: Bedingt Prozedur aufrufen
 
Zitat:

Zitat von CRoSSi
:wiejetzt:
wie mache ich das?
mir reicht das schon wenn var=1 ist dass er dann die die funktion aufruft? weil var ist entweder 1 oder 0 bei 0 soll er einfach weiter machen und bei 1 soll die funktion geladen werden. Mehr brauche ich ja nicht. Das würde locker reichen.. Aber da ist das große fragezeichen wie macht man sowas am besten?

thx schonmal

Man hat Dir Links zu Tutorials gegeben.
Diese sind sehr gut und eigentlich auch verständlich geschrieben.

Setz Dich also hin und arbeite diese Tutorials Schritt für Schritt durch.
Eventuell solltest Du auch ein kleines Testprojekt der Tutorials durcharbeiten oder selber eines anlegen.

Es wird Dir hier niemand eine fertige Lösung zusammenschustern.
Eigeninitiative ist gefragt.

CRoSSi 24. Jan 2008 11:09

Re: Bedingt Prozedur aufrufen
 
Ja ich arbeite mich jetzt das tutorial mal durch muss da nur gucken wie ich das zeitlich halt schaffe..mache das ja nicht hauptberuflich.. :-D

aber danke an alle für die antworten

CRoSSi 30. Jan 2008 12:37

Re: Bedingt Prozedur aufrufen
 
So ich habe mir das Tut usw mal angeschaut und noch nen bisschen gegoogelt und habe mal einige versuche gestartet..aber leider erfolgslos. Poste hier mal den Quelltext einer kleinen Test Unit evtl habt ihr ein paar vorschläge warum das nicht geht. Bin ja nicht so der fiteste im Programmieren. Hoffe deshalb auf weitere gute Lösungsansätze.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);

  private
    { Private-Deklarationen }

  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;


implementation

{$R *.dfm}
type TPortOut = procedure(Port:Word;Data:Byte); stdcall;

var  PortOut: TPortOut;
      Handle: THandle;

procedure TForm1.Button1Click(Sender: TObject);
begin
Handle := LoadLibrary(PChar(ExtractFilePath(ParamStr(0))+'io.dll'));
if Handle <> 0 then begin
  @PortOut := GetProcAdress(Handle, 'PortOut');
  if @PortOut <> nil then begin
  PortOut($378,255);
  end;
FreeLibrary(Handle);
end;

end.
Hoffe habe das jetzt so halbwegs verstanden
Danke für antworten

oki 30. Jan 2008 14:22

Re: Bedingt Prozedur aufrufen
 
So wird ein Schuh draus:
Delphi-Quellcode:

{$R *.dfm}
type TPortOut = procedure(Port:Word;Data:Byte); stdcall;

var  PortOut: TPortOut = nil;
      AHandle: THandle = 0;

implementation

procedure TForm1.Button1Click(Sender: TObject);
begin
  AHandle := LoadLibrary('io.dll');
  if AHandle <> 0 then begin
    PortOut := GetProcAdress(AHandle, 'PortOut');
    if PortOut <> nil then begin
    PortOut($378,255);
  end;
  FreeLibrary(AHandle);
end;
Gruß oki

[edit] Handle auf AHandle [/edit oki]


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:44 Uhr.
Seite 2 von 4     12 34      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz