Entwickler-Ecke

Dateizugriff - Probleme beim auslagern eines Programmteils in eine DLL


Henry - Di 21.10.03 21:12
Titel: Probleme beim auslagern eines Programmteils in eine DLL
Hallo,

ich habe folgendes Problem:
Ich möchte eine Procedure die den unten anegebenen Teil enthält in eine DLL auslagern.
Aber wenn ich dann diese Procedure aufrufe, dann wird kein Menu erzeugt, wenn ich aber die Unit direkt in das Programm einbinde, dann funktioniert es. Der Code ist also voll funktionsfähig.
Woran kann es liegen das der Code nicht aus einer DLL heraus funktioniert?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
Procedure LoadPlugins(Pfad: String; Pluginmenu:TMenuItem);
VAR Suchergebnis  : TSearchRec;

    Plugin        : TPlugin;
    NewItem       : TMenuItem;
    GetPluginName : TGetPluginName;
    Pluginversion : TPluginVersion;
    I             : Integer;

...

  Begin
   FreeLibrary(Plugins_[Count_]);
   ShowMessage('Die Datei:' + #13 +
                Items.Strings[i] + #13 +
               'ist keine Plugindatei und Wurde nicht geladen!' + #13 +
               'Sie sollte aus dem Pluginverzeichnis entfernt werden.');
  End //If GetProcAddress
   Else
    Begin
     GetPluginName := TGetPluginName(GetProcAddress(Plugins_[Count_],'pluginname'));
     PluginVersion := TPluginversion(GetProcAddress(Plugins_[Count_],'pluginversion'));
  //Neuen Menüeintrag für jedes gefundene Plugin erzeugen
     NewItem         := TMenuItem.Create(nil);
     Newitem.Caption := GetPluginName;
     NewItem.Tag     := Count_;
   //Fehlermeldung bei nichtbekannter Pluginversion (muß aktuallisiert werden
   //wenn eine neue Version hizukommt
    If Pluginversion > 0 then
     Begin
      ShowMessage('Die Version der Plugindatei' + #13 +
                   Items.Strings[i] + #13 +
                  'ist zu neu. Bitte die aktuelle Pluginschnittstellenversion' +
                  ' herunterladen.');
  End;

...

End;


Übergeben tue ich die Parameter wie folgt:

Delphi-Quelltext
1:
loadplugin('C:/ordner', Plugin1);                    

Plugin1 ist ein Item des MainMenu.

Herzlichen Dank im voraus


mirage228 - Di 21.10.03 21:16

Hi,

du musst irgendwo auch noch ein TMainMenu.Items[<Index>].Add(NewItem); durchführen...


also das das erstellte Menü auch dem Hauptmenü hinzugefügt wird!

mfG
mirage228


Henry - Di 21.10.03 21:38

Es besteht bereits ein Menü in meinem TMainmenu. Diesen Eintrag mache ich in Abhängigkeit vom vorhanden sein einer Datei sichtbar.
Und wie gesagt, wenn ich die Procedure aus einer Unit heraus ausführe funktioniert es.
Es muß meiner Meinung nach mit dem auslagern in die DLL zusammenhängen.


Tino - Mi 22.10.03 09:45

Hallo,

ich glaube du hast mirage228´s Antwort nicht ganz verstanden. Du erstellst zwar ein TMenuItem aber mehr auch nicht. Du musst dieses TMenuItem auch dem Menü hinzufügen.

Gruß
Tino


Henry - Mi 22.10.03 18:35

Das kann sein.
Ich werde mich nochmal damit auseinandersetezn, mal schauen ob ich es doch noch hinbekomme.


Tino - Do 23.10.03 11:37

Hallo!

Du must halt nach dem du den MenuItem erstellt hast:

Delphi-Quelltext
1:
2:
3:
     NewItem         := TMenuItem.Create(nil); 
     Newitem.Caption := GetPluginName; 
     NewItem.Tag     := Count_;

Diesen auch dem Menu hinzufügen:

Delphi-Quelltext
1:
Pluginmenu.Items.Add (NewItem);                    

Gruß
Tino


Henry - Do 23.10.03 19:52

Hallo nochmal zusammen,

@Tino: es hatte sich herausgestellt das ich das schon drin hatte, nur etwas tiefer als ich gepostet habe.

Es hat leider trotzdem nicht funktioniert. Es liegt aber definitiv an der Procedure in der DLL, denn wenn ich sie ausklammere dann startet das Programm ohne Probleme.
Ich habe mal die ganze Procedure mit eingefügt, vieleicht ist ja da was anderes grundlegendes falch.
Wie ich oben schon schrieb, wenn ich exakt die selbe Procedure in eine Unit packe und die einbunde dann funktioniert sie ohne Probleme.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
Procedure LoadPlugins(Pfad: String; Pluginmenu:TMenuItem);
VAR Suchergebnis  : TSearchRec;

    Plugin        : TPlugin;
    NewItem       : TMenuItem;
    GetPluginName : TGetPluginName;
    Pluginversion : TPluginVersion;
    I             : Integer;

Begin

//PluginNamen herausfinden (DLLs im Verzeichnis suchen)
 Pfad  := IncludeTrailingBackslash(Pfad);
 Items := TStringList.Create;
 Plugin:= TPlugin.Create;


 If FindFirst(Pfad + '*.dll', faAnyFile, Suchergebnis) = 0 then
  Begin
   Repeat
    Items.Add(Pfad + Suchergebnis.Name);
   Until FindNext(Suchergebnis) <> 0;
   FindClose(suchergebnis);
  End;

//*****************************************************************************

//DLL Dateien laden
//MenuItems erstellen für jedes Plugin was sich im Verzeichnis befiondet

 For i := 0 to Items.Count - 1 do
  Begin
  //Alle DLLs im Verzeichnis Laden
   Plugins_[Count_] := LoadLibrary(PChar(Items.Strings[i]));

 If (GetProcAddress(Plugins_[Count_],'pluginname') = Nilor
    (GetProcAddress(Plugins_[Count_],'pluginstart') = Nilor
    (GetProcAddress(Plugins_[Count_],'pluginversion') = Nil)
    then
  Begin
   FreeLibrary(Plugins_[Count_]);
   ShowMessage('Die Datei:' + #13 +
                Items.Strings[i] + #13 +
               'ist keine Plugindatei und Wurde nicht geladen!' + #13 +
               'Sie sollte aus dem Pluginverzeichnis entfernt werden.');
  End //If GetProcAddress
   Else
    Begin
     GetPluginName := TGetPluginName(GetProcAddress(Plugins_[Count_],'pluginname'));
     PluginVersion := TPluginversion(GetProcAddress(Plugins_[Count_],'pluginversion'));
  //Neuen Menüeintrag für jedes gefundene Plugin erzeugen
     NewItem         := TMenuItem.Create(nil);
     Newitem.Caption := GetPluginName;
     NewItem.Tag     := Count_;

   //Fehlermeldung bei nichtbekannter Pluginversion 
   
    If Pluginversion > 0 then
     Begin
      ShowMessage('Die Version der Plugindatei' + #13 + 
                   Items.Strings[i] + #13 + 
                  'ist zu neu. Bitte die aktuelle Pluginschnittstellenversion' + 
                  ' herunterladen.');
     End;
   //Ende Fehlermeldung

   //OnClickereignis bei Version 0
    If Pluginversion = 0 then
     Begin
      NewItem.OnClick := Plugin.PluginsOnClick;
     End;
   //OnClickereignis bei Version 1
     PluginMenu.Add(NewItem);
     Inc(Count_);
    End;

 End;//For...

//*****************************************************************************

 

//Freigeben
 Items.Free;
End;


Ansonsten werde ich es wohl als Unit integrieren müßen. Mir wäre aber wegen der Flexibilität eine DLL lieber.