Seite 1 von 1

Fragen über DLLs und Programmierung von Plugins

Verfasst: 30.06.2014 14:21
von SBond
Hi Leute, ich habe mal wieder ein paar Fragen an euch. Ich möchte gerne eine Oberfläche programmieren, die sich dynamisch über Plugins (als DLLs) erweitern lässt. Ich habe im Vorfeld noch nie groß mit DLLs gearbeitet und weiß nicht, ob es irgendwo Probleme geben könnte...

1. Frage: kann man in PureBasic DLLs debuggen?
Bei normalen ausführbaren Programmen ist es ja kein Problem.... Debugger anschalten.... und debuggen ;)
Bei DLLs weiß ich nicht so recht ob es geht, da die DLL nicht direkt ausgeführt wird.

2. Frage: Ist es möglich ein Projekt so zu kompilieren, dass neben dem Hauptprogramm auch Plugins mitkompiliert werden?
Normalerweise gibt man ja den absoluten Pfad und Dateinamen der kompilierten Datei an. ...aber kann man auch mehrere Dateien gleichzeitig bzw. nacheinander kompilieren (z.B. eine .exe und mehrere .dll)?

3. Frage: kann man aus einer DLL heraus Prozeduren des Hautprogramms starten?
Um auf Funktionen in einer DLL zuzugreifen, kann man Prototypes verwenden. ....aber geht dies auch anders herum?

4. Frage: Gibt es wichtige Regeln die man beachten muss, wenn man DLLs programmiert?
z.B. Übergabe von Zeigern; Sichtbarkeit von Variablen; mögliche Probleme bei Multithreading; .....

5. Frage: ein Beispiel:

Hauptprogramm:

Code: Alles auswählen

Prototype Plugin_init (iWindowID.i, iPanel.i)

Global iWindow.i
Global iPanel.i
Global iDLL_Dir_ID.i

Structure Plugin_Struktur
	DLL_ID.i
	fkt_init.Plugin_init
EndStructure

NewList Plugin_List.Plugin_Struktur()

; Plugins suchen und aufnehmen
DLL_Dir_ID = ExamineDirectory(#PB_Any, "plugins/", "*.dll")
While NextDirectoryEntry(DLL_Dir_ID)
	AddElement(Plugin_List())
	With Plugin_List()
		\DLL_ID 	= OpenLibrary(#PB_Any, "plugins/" + DirectoryEntryName(DLL_Dir_ID))
		\fkt_init 	= GetFunction(\DLL_ID, "Init")
	EndWith
Wend

; GUI erstellen
iWindow	= OpenWindow	(#PB_Any,  0,  0, 400, 300, "Plugins", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget)
iPanel	= PanelGadget	(#PB_Any, 10, 100, 380, 180)

; Plugins initialisieren
ForEach Plugin_List()
	Plugin_List()\fkt_init(WindowID(iWindow), iPanel)
Next

Repeat: Until WaitWindowEvent(50) = #PB_Event_CloseWindow

Plugin:

Code: Alles auswählen

ProcedureDLL Init(iWindowID.i, iPanel.i)
	
	; Button in GUI erstellen
	UseGadgetList(iWindowID)
	ButtonGadget(#PB_Any, 10, 10, 140, 40, "Button Plugin 1")
	
	OpenGadgetList(iPanel)
	AddGadgetItem (iPanel, 0, "Plugin 1 - Tab 1")
	ButtonGadget(#PB_Any, 20, 20, 140, 40, "Button Plugin 2")
	AddGadgetItem (iPanel, 1, "Plugin 1 - Tab 2")
	ButtonGadget(#PB_Any, 20, 50, 140, 40, "Button Plugin 3")
	CloseGadgetList()
	
	ProcedureReturn 0
	
EndProcedure
Ich möchte Plugins in einer GUI einbinden. Dazu sollen Gadgets in einem PanelGadget hinzugefügt werden. In dem Fenster kann ich zwar Gadgets hinzufügen, aber nicht in dem PanelGadget. Außerdem stürzt das Programm sofort ab, wenn ich es außerhalb der PureBasic IDE starte.

Was mache ich falsch?


viele Grüße,
SBond

Re: Fragen über DLLs und Programmierung von Plugins

Verfasst: 30.06.2014 18:09
von edel
1. Der Debugger von PB unterstützt das nicht, du kannst aber z.b. WinDbg nehmen oder einfach ein Konsolenfenster oeffnen und dein Zeug ueber Print ausgeben. Du musst nur darauf achten, dass das Konsolenfenster nicht von dir selber geschlossen wird, sonst haengt dein Programm.

2. Ja das geht. Über ein Projekt kannst du deine "Ziele" erstellen und mit einem Rutsch alles kompilieren.

3. Jop, das geht genauso.

5. Das geht deshalb nicht, weil die DLL ihren eigene "Gadgetliste", "Fensterliste" oder was auch immer hat.
Deine DLL kann also die Gadgets in deinem Hauptprogramm gar nicht finden. Du kannst das ganze umgehen, indem du einen Zeiger auf eine Funktion in deinem Hauptprogramm uebergibst, und die Funktion aus der DLL aufrufst.

In deinem Beispiel liest du alle DLLs ein und laesst dir den Zeiger der Funktion geben, was aber wenn es diese Funktion gar nicht gibt?
Dein Programm schmiert ab. Prüfe lieber vorher, ob es sich auch tatsaechlich um eines deiner Plugins handelt und erstelle erst dann ein neues Element.