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 Anfängerfrage zu DLL (https://www.delphipraxis.net/146337-anfaengerfrage-zu-dll.html)

iphi 18. Jan 2010 12:25


Anfängerfrage zu DLL
 
Hallo,

ich möchte einen Teil meines Codes in eine DLL auslagern.
Bei welcher Gelegenheit erzeugt man denn innerhalb der DLL lokale Datenstrukturen, die so lange leben sollen wie die DLL geladen ist?
Gibt es bei einer DLL so etwas wie einen OnLoad-Event oder muss ich hierfür in der DLL einfach eine Ini-Prozedur vorsehen, die ich dann zu Fuß aufrufen muss?

Danke, Thomas

mkinzler 18. Jan 2010 12:27

Re: Anfängerfrage zu DLL
 
Dafür dient der Initialisierungsteil der Dll

Medium 18. Jan 2010 12:27

Re: Anfängerfrage zu DLL
 
Ich würde solche Dinge im initialization und finalization Teil machen.

iphi 18. Jan 2010 15:13

Re: Anfängerfrage zu DLL
 
Wie sieht denn die Initialization und Finalization Struktur in einer DLL aus?

Delphi-Quellcode:
library test;


uses
  SysUtils,
  Classes,

{$R *.res}

function DLLpi(i,j:integer): integer; cdecl; export;
begin
  Result:=314*i+j ;
end;

exports DLLpi;

initialization
;

finalization
;

begin
end.
So compiliert das nicht.

mkinzler 18. Jan 2010 15:14

Re: Anfängerfrage zu DLL
 
Es steht ja uch nichts drin.

iphi 18. Jan 2010 15:23

Re: Anfängerfrage zu DLL
 
Der Compiler stört sich an Initialization an dieser Stelle, nicht daran, dass nicts drin steht.

Kann mir bitte jemand ein kurzes Beispiel zeigen wie die DLL-Struktur mit Initialisierung und Abschluss richtig aussehen muss?
Danke.

Luckie 18. Jan 2010 15:33

Re: Anfängerfrage zu DLL
 
Schon mal Google bemüht? Bei Google suchenDelphi DLL Tutorial

iphi 18. Jan 2010 15:37

Re: Anfängerfrage zu DLL
 
Zitat:

Schon mal Google bemüht?
Ja, aber diesen Punkt lassen die Tutorials geflissentlich aus.
Ich dachte, hier kann mir jemand helfen.

sirius 18. Jan 2010 16:03

Re: Anfängerfrage zu DLL
 
Suche mal nach DLLMain!

Medium 18. Jan 2010 16:15

Re: Anfängerfrage zu DLL
 
Die Abschnitte gehören zwischen "begin..end;" und dem "end." Also nach dem quasi "Hauptprogramm", nicht davor.

iphi 18. Jan 2010 20:18

Re: Anfängerfrage zu DLL
 
Zitat:

Suche mal nach DLLMain!
Danke, das war sehr hilfreich!
Der Teil zwischen begin ... end. wird beim Laden der DLL durchlaufen, richtig?
Da kann ich meine DLL-Callback Funktion setzen.

Noch eine Frage:
Ich möchte in meiner DLL eine Komponente benutzen, die normalerweise auf einer Form "lebt".
Kann ich innerhalb der DLL ein unsichtbares Fenster erzeugen und wenn ja, wie?
Kann dieses unsichtbare Fenster dann auch Windowsmessages empfangen?

Zitat:

Die Abschnitte gehören zwischen "begin..end;" und dem "end." Also nach dem quasi "Hauptprogramm", nicht davor.
Kann es sein, dass das nur in einer Unit, nicht aber in einer Library so funktioniert?

sirius 19. Jan 2010 17:05

Re: Anfängerfrage zu DLL
 
Zitat:

Zitat von iphi
Zitat:

Suche mal nach DLLMain!
Danke, das war sehr hilfreich!
Der Teil zwischen begin ... end. wird beim Laden der DLL durchlaufen, richtig?

Hmmm, naja. Du musst erstmal wisse, wo eine DLL im Speicher liegt, und dann wie die verschiedenen Prozesse auf diese DLL darauf zugreifen und wann sie wirklich "entladen" wird.

Zitat:

Da kann ich meine DLL-Callback Funktion setzen.
Was für eine Callback-Funktion?

Zitat:

Noch eine Frage:
Neues Thema, oder?

Zitat:

Ich möchte in meiner DLL eine Komponente benutzen, die normalerweise auf einer Form "lebt".
Kann ich innerhalb der DLL ein unsichtbares Fenster erzeugen und wenn ja, wie?
Kann dieses unsichtbare Fenster dann auch Windowsmessages empfangen?
Was ist das für eine Komponente? Nur eine Komponente oder gleich ein Control?
Auch unsichtbare Fenster empfangen Nachrichten (das unsichtbarste Fenster kannst du mit "allocatehwnd" erstellen). Das Problem kann bei dir nur sein, dass die Nachrichtenschleife im Hauptprogramm ist. Das solltest du im Auge behalten.

Zitat:

Kann es sein, dass das nur in einer Unit, nicht aber in einer Library so funktioniert?
[/quote]
jep. Wobei auch Librarys aus mehreren Units bestehen können. Aber das Hauptprogram (*.dpr) kennt keine derartigen Abschnitte. Und ich erinnere mich dunkel, dass die Library in Units diese Abschnitte nicht oder nur bedingt ausführt.

MisterNiceGuy 19. Jan 2010 17:24

Re: Anfängerfrage zu DLL
 
OT: Yeah, an 6. Stelle steht bei Google mein DLL-Tutorial :D

iphi 19. Jan 2010 20:53

Re: Anfängerfrage zu DLL
 
Zitat:

Was für eine Callback-Funktion?
DLLMain ist doch so was wie eine Callback Funktion.
DLLProc wird die Adresse von DLLMain zugewiesen, so dass DLLMain beim Laden und Entladen der DLL aufgerufen wird. Die Zuweisung findet wohl sinnvollerweise in dem begin ... end. Block der DLL statt.
Das funktioniert so weit prima.

Zitat:

Was ist das für eine Komponente?
Es geht um die TJvHidDeviceController-Komponente, die ich in eine DLL kapseln will.
Wen lasse ich da den DeviceChange-Event empfangen, wenn mein TJvHidDeviceController-Objekt kein Fenster als Ahn hat?

Wal 25. Jan 2010 07:04

Re: Anfängerfrage zu DLL
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hatte mal eine Ansteuerung für ein USBRadio(jvhidkompo) mit Callbackfunktion in eine Dll umgesetzt, evtl. kann es für dich nützlich sein.
Die Ansteuerung war nicht von mir, nur die Dll-Umsetzung.

Das Laden der Dll und Auswerten des Callback ging so:

Delphi-Quellcode:
unit RadioDllWrapper;

interface

uses Windows, StrUtils, IniFiles;

type
  TFNInitRadio = procedure(strPath: PChar); stdcall;
  TFNCloseRadio = procedure; stdcall;
  TFNSetRadioFrequenz = procedure(Value: Integer; Tuner: Boolean); stdcall;
  TFNSetRadioIntervall = procedure(Value: Integer); stdcall;
  TFNScanRadio = procedure(direction: Boolean; Tuner: Boolean); stdcall;
  TFNSeekRadio = procedure(direction: Boolean; Tuner: Boolean); stdcall;
  TFNSetRadioVolume = procedure(Value: Integer); stdcall;
  TFNSetRadioBass = procedure(Value: Integer); stdcall;
  TFNSetRadioTreble = procedure(Value: Integer); stdcall;
  TFNSetRadioLoudnessOn = procedure(Value: Boolean); stdcall;
  TFNSetRadioLoudnessStep = procedure(Value: Boolean); stdcall;
  TFNSetRadioVolumeStep = procedure(Value: Boolean); stdcall;
  TFNSetRadioFaderStep = procedure(Value: Boolean); stdcall;
  TFNSetRadioBalanceStep = procedure(Value: Boolean); stdcall;
  TFNSetRadioBassStep = procedure(Value: Boolean); stdcall;
  TFNSetRadioTrebleStep = procedure(Value: Boolean); stdcall;
  TFNSetRadioMute = procedure(Value: Boolean); stdcall;
  TFNSetRadioRemote = procedure(Value: Boolean); stdcall;
  TFNSetRadioLoudness = procedure(Value: Integer); stdcall;
  TFNSetRadioBalance = procedure(Value: Integer); stdcall;
  TFNSetRadioFader = procedure(Value: Integer); stdcall;
  TFNSetRadioAntenne = procedure(Tuner: Boolean; Antenne: Boolean); stdcall;
  TFNSetRadioAFOn = procedure(Value: Boolean); stdcall;
  TFNSaveRadioValue = procedure; stdcall;
  TFNRadioCallBack = procedure(Value: Pointer); stdcall;

  function LoadRadioDll: Boolean;
  function CloseRadioDll: Boolean;

  //Dll-Callback
  procedure RCallBack(Index: Integer; Data: PChar; IntData: Integer);

const
  RADIO_CLOSE          = 0;
  RADIO_OPEN           = 1;
  RADIO_FRQ1            = 2;
  RADIO_FRQ2            = 3;
  RADIO_PI1             = 4;
  RADIO_PI2             = 5;
  RADIO_FS1             = 6;
  RADIO_FS2             = 7;
  RADIO_RDSNAME1        = 8;
  RADIO_RDSNAME2        = 9;
  RADIO_RDSTEXT1        = 10;
  RADIO_RDSTEXT2        = 11;
  RADIO_PTY1            = 12;
  RADIO_PTY2            = 13;
  RADIO_MONO1           = 14;
  RADIO_MONO2           = 15;
  RADIO_TP1             = 16;
  RADIO_TP2             = 17;
  RADIO_INTERVALL      = 200;
  RADIO_REMOTE         = 201;
  RADIO_ERROR          = 255;
  RADIO_MESSAGE        = 100;

 
var
  InitRadio: TFNInitRadio= nil;
  CloseRadio: TFNCloseRadio = nil;
  SetRadioFrequenz: TFNSetRadioFrequenz = nil;
  SetRadioIntervall: TFNSetRadioIntervall = nil;
  ScanRadio: TFNScanRadio = nil;
  SeekRadio: TFNSeekRadio = nil;
  SetRadioVolume: TFNSetRadioVolume = nil;
  SetRadioBass: TFNSetRadioBass = nil;
  SetRadioTreble: TFNSetRadioTreble = nil;
  SetRadioLoudnessOn: TFNSetRadioLoudnessOn = nil;
  SetRadioLoudnessStep: TFNSetRadioLoudnessStep = nil;
  SetRadioVolumeStep: TFNSetRadioVolumeStep = nil;
  SetRadioFaderStep: TFNSetRadioFaderStep = nil;
  SetRadioBalanceStep: TFNSetRadioBalanceStep = nil;
  SetRadioBassStep: TFNSetRadioBassStep = nil;
  SetRadioTrebleStep: TFNSetRadioTrebleStep = nil;
  SetRadioMute: TFNSetRadioMute = nil;
  SetRadioRemote: TFNSetRadioRemote = nil;
  SetRadioLoudness: TFNSetRadioLoudness = nil;
  SetRadioBalance: TFNSetRadioBalance = nil;
  SetRadioFader: TFNSetRadioFader = nil;
  SetRadioAntenne: TFNSetRadioAntenne = nil;
  SetRadioAFOn: TFNSetRadioAFOn = nil;
  SaveRadioValue: TFNSaveRadioValue = nil;
  RadioCallBack: TFNRadioCallBack = nil;
  RadioLib: HMODULE;


implementation

uses
  Radio, RadioUnit;

function LoadRadioDll: Boolean;
var
  ini: TMemIniFile;
  RadioDll: String;
begin
  result := False;
  try
    Ini:=TMemIniFile.Create('Radio.ini');
    RadioDll := Ini.ReadString('Global','RadioDll','');
  finally
    ini.Free;
  end;
  if RadioDll <> '' then
  RadioLib := LoadLibrary(PChar(RadioDll));
  if RadioLib <> 0 then
  begin
    @InitRadio := GetProcAddress(RadioLib, 'InitRadio');
    @CloseRadio := GetProcAddress(RadioLib, 'CloseRadio');
    @SetRadioFrequenz := GetProcAddress(RadioLib, 'SetRadioFrequenz');
    @SetRadioIntervall := GetProcAddress(RadioLib, 'SetRadioIntervall');
    @ScanRadio := GetProcAddress(RadioLib, 'ScanRadio');
    @SeekRadio := GetProcAddress(RadioLib, 'SeekRadio');
    @SetRadioVolume := GetProcAddress(RadioLib, 'SetRadioVolume');
    @SetRadioBass := GetProcAddress(RadioLib, 'SetRadioBass');
    @SetRadioTreble := GetProcAddress(RadioLib, 'SetRadioTreble');
    @SetRadioLoudnessOn := GetProcAddress(RadioLib, 'SetRadioLoudnessOn');
    @SetRadioLoudnessStep := GetProcAddress(RadioLib, 'SetRadioLoudnessStep');
    @SetRadioVolumeStep := GetProcAddress(RadioLib, 'SetRadioVolumeStep');
    @SetRadioFaderStep := GetProcAddress(RadioLib, 'SetRadioFaderStep');
    @SetRadioBalanceStep := GetProcAddress(RadioLib, 'SetRadioBalanceStep');
    @SetRadioBassStep := GetProcAddress(RadioLib, 'SetRadioBassStep');
    @SetRadioTrebleStep := GetProcAddress(RadioLib, 'SetRadioTrebleStep');
    @SetRadioMute := GetProcAddress(RadioLib, 'SetRadioMute');
    @SetRadioRemote := GetProcAddress(RadioLib, 'SetRadioRemote');
    @SetRadioLoudness := GetProcAddress(RadioLib, 'SetRadioLoudness');
    @SetRadioBalance := GetProcAddress(RadioLib, 'SetRadioBalance');
    @SetRadioFader := GetProcAddress(RadioLib, 'SetRadioFader');
    @SetRadioAntenne := GetProcAddress(RadioLib, 'SetRadioAntenne');
    @SetRadioAFOn := GetProcAddress(RadioLib, 'SetRadioAFOn');
    @SaveRadioValue := GetProcAddress(RadioLib, 'SaveRadioValue');
    @RadioCallBack := GetProcAddress(RadioLib, 'RadioCallBack');
    result := True;
  end;
end;


function CloseRadioDll: Boolean;
begin
  if RadioLib <> 0 then
  begin
    FreeLibrary(RadioLib);
    result := True;
  end else
    result := False;
end;


//Diese Funktion soll das Hauptprogramm aufrufen bei einer Dll-Nachricht
procedure RCallBack(Index: Integer; Data: PChar; IntData: Integer);
begin
  case Index of
  RADIO_CLOSE    : begin RadioOn := False; end;
  RADIO_OPEN     : begin
                      SetRadioFrequenz(LastRadioFrq, False);
                      SetRadioMute(False);
                      if RadioAF then SetRadioAFOn(True);
                      RadioOn := True;
                    end;
  RADIO_FRQ1      : begin
                      frmMain.Flash.SetVariable('RADIOFREQ', String(Data));
                      RadioFrequenz1 := String(Data);
                      Frequenz := IntData;
                    end;
  RADIO_FRQ2      : begin frmMain.Flash.SetVariable('AFFREQ', String(Data)); end;
  RADIO_PI1       : begin
                      frmMain.Flash.SetVariable('PICODE', String(Data));
                      PICode := String(Data);
                      frmMain.Flash.SetVariable('RADIOLOGO', AppPath + '\Radio\' + PICode + '.jpg');
                    end;
  RADIO_PI2       : begin frmMain.Flash.SetVariable('AFPICODE', String(Data)); end;
  RADIO_FS1       : begin frmMain.Flash.SetVariable('RDSSIGNAL', String(Data)); end;
  RADIO_FS2       : begin frmMain.Flash.SetVariable('AFFS', String(Data)); end;
  RADIO_RDSNAME1  : begin
                      frmMain.Flash.SetVariable('RDSNAME', String(Data));
                      Radioname := String(Data);
                    end;
  RADIO_RDSNAME2  : begin end;
  RADIO_RDSTEXT1  : begin
                      frmMain.Flash.SetVariable('RDSTEXT', String(Data));
                    end;
  RADIO_RDSTEXT2  : begin end;
  RADIO_PTY1      : begin frmMain.Flash.SetVariable('RADIOGENRE', String(Data)); end;
  RADIO_PTY2      : begin end;
  RADIO_MONO1     : begin frmMain.Flash.SetVariable('RADIOSTEREO', String(Data)); end;
  RADIO_MONO2     : begin end;
  RADIO_TP1       : begin frmMain.Flash.SetVariable('TP', String(Data)); end;
  RADIO_TP2       : begin end;
  RADIO_INTERVALL : begin OutputDebugString(Data); end;
  RADIO_REMOTE   : begin frmMain.Remote(IntData); end;
  RADIO_ERROR    : begin OutputDebugString(Data); end;
  RADIO_MESSAGE  : begin OutputDebugString(Data); end;
  end;
end;


end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:45 Uhr.

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