PB DLL als Modul im Hauptcode
-
- Beiträge: 250
- Registriert: 25.11.2004 19:51
- Computerausstattung: Alienware Aurora / Intel Core i7 CPU @ 2.8 GHz / 64 Bit OS
PB DLL als Modul im Hauptcode
Hallo zusammen,
ich versuche derzeit eine kleine eigene Sidebar in einem größeren Projekt zu realisieren.
Meine Idee war es diverse Sidebar Gadgets als DLL in mein Projekt einzubinden. Prinzipiell ist dies auch kein Problem.
Allerdings wenn ich auf Variablen aus meinem - nennen wir es mal "Regiezentrum" zurückgreifen möchte ecke ich an.
Ist dies überhaupt so realisierbar, dass aus einer DLL auf Globale Variablen des Hauptprogramms zurückgreifen kann?
Zudem die Frage - bzw. kann es sein, dass man auf Enumerationen eben sowenig zurückgreifen kann?
LG derweil
ich versuche derzeit eine kleine eigene Sidebar in einem größeren Projekt zu realisieren.
Meine Idee war es diverse Sidebar Gadgets als DLL in mein Projekt einzubinden. Prinzipiell ist dies auch kein Problem.
Allerdings wenn ich auf Variablen aus meinem - nennen wir es mal "Regiezentrum" zurückgreifen möchte ecke ich an.
Ist dies überhaupt so realisierbar, dass aus einer DLL auf Globale Variablen des Hauptprogramms zurückgreifen kann?
Zudem die Frage - bzw. kann es sein, dass man auf Enumerationen eben sowenig zurückgreifen kann?
LG derweil
PB 4.6 / 32 Bit / 64 Bit
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: PB DLL als Modul im Hauptcode
Die DLL kennt die globalen Variablen des Programmes nicht, und umgekehrt kennt das Programm die globalen Variablen der DLL nicht.
Enumerationen sind konstanten und sind der DLL auch nicht von Hause aus bekannt.
Enumerationen sind konstanten und sind der DLL auch nicht von Hause aus bekannt.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Re: PB DLL als Modul im Hauptcode
Eine DLL ist nichts weiter als eine selbständiges "Programm", das lediglich
seine Funktionalität anderen Programmen zur Verfügung stellt. Weder
das aufrufende Programm, noch die DLL haben irgend welche Kenntnis
über den jeweils anderen. Programme können lediglich auslesen, welche
Prozeduren eine DLL zur Verfügung stellt und darauf zugreifen.
MFG PMV
seine Funktionalität anderen Programmen zur Verfügung stellt. Weder
das aufrufende Programm, noch die DLL haben irgend welche Kenntnis
über den jeweils anderen. Programme können lediglich auslesen, welche
Prozeduren eine DLL zur Verfügung stellt und darauf zugreifen.
MFG PMV
Re: PB DLL als Modul im Hauptcode
Dafür eignen sich Includes hervorragendsmateja hat geschrieben:Zudem die Frage - bzw. kann es sein, dass man auf Enumerationen eben sowenig zurückgreifen kann?

Dann haste zumindest mal alle Konstanten verfügbar ohne alles doppelt machen zu müssen.
Variablen musst du halt im Prozedurparameter übergeben oder du suchst mal nach Shared Memory hier im Forum.
-
- Beiträge: 250
- Registriert: 25.11.2004 19:51
- Computerausstattung: Alienware Aurora / Intel Core i7 CPU @ 2.8 GHz / 64 Bit OS
Re: PB DLL als Modul im Hauptcode
Merci erstmal für die Infos - das mit den includes für Enumerationen etc - ist schon mal ein sehr guter Anfang.
Habt ihr evtl. Ideen dennoch einen Datenaustausch zwischen DLL und Hauptprogramm zu realisieren.
Oder auch ganz anders gedacht - wie realisiert man Plugins für ein Programm?
LG
Habt ihr evtl. Ideen dennoch einen Datenaustausch zwischen DLL und Hauptprogramm zu realisieren.
Oder auch ganz anders gedacht - wie realisiert man Plugins für ein Programm?
LG
PB 4.6 / 32 Bit / 64 Bit
Re: PB DLL als Modul im Hauptcode
Also ich würde das wie folgt versuchen.
Erst mal überlegen, was ein Plugin alles können muss.
zB. Einen Menüeintrag (oder ein ganzes Submenu) in der Menubar unter "Plugins" erstellen. (Datei, Bearbeiten, Ansicht, Plugins, Hilfe...).
Oder einen Button in der Toolbar erstellen.
Dann legt man fest, wie die Funktionen heißen müssen. Z.B. MyProg_Plugin_Init(param...), MyProg_Plugin_Main(param....)
Diese Funktionen werden vom Hauptprogramm mit entsprechenden Parametern aufgerufen (ein wichter Parameter wäre z.B. hWnd, also WindowID(#Window_0), oder auch EventGadget(), EventType() etc, je nach Programmtyp).
Zum Datenaustausch wie gesagt SharedMemory, wenn die DLL eher ein eigenständiges Programm ist.
Für einfache Rückgabewerte kann man einfach ProcedureReturn benutzen.
Hier mal mein angefangens Mini-Pluginsystem (ohne Shared Memory)
Das ist natürlich ein dämliches Plugin, dass nicht's kann. Außerdem ist die absolute Position des Buttons mehr als ungünstig. X und Y Position sollte evtl vom Hauptprogramm an die DLL übergeben werden...
Aber ist ja nur ein kleines Beispiel
Erst mal überlegen, was ein Plugin alles können muss.
zB. Einen Menüeintrag (oder ein ganzes Submenu) in der Menubar unter "Plugins" erstellen. (Datei, Bearbeiten, Ansicht, Plugins, Hilfe...).
Oder einen Button in der Toolbar erstellen.
Dann legt man fest, wie die Funktionen heißen müssen. Z.B. MyProg_Plugin_Init(param...), MyProg_Plugin_Main(param....)
Diese Funktionen werden vom Hauptprogramm mit entsprechenden Parametern aufgerufen (ein wichter Parameter wäre z.B. hWnd, also WindowID(#Window_0), oder auch EventGadget(), EventType() etc, je nach Programmtyp).
Zum Datenaustausch wie gesagt SharedMemory, wenn die DLL eher ein eigenständiges Programm ist.
Für einfache Rückgabewerte kann man einfach ProcedureReturn benutzen.
Hier mal mein angefangens Mini-Pluginsystem (ohne Shared Memory)
Code: Alles auswählen
;Main.pb
EnableExplicit
Define PS_PluginPath .s = "plugins/" ;Pfad und ID des Plugin Ordners.
Define PS_PluginDirectoryID .i
Define.i WindowEvent, EventGadget, Main_WindowID
Prototype proto_init(hWnd.i) ;Prototypen der Plugin-Funktionen
Prototype proto_eventgadget(eventgadget.i)
Structure plugins_structure ;Struktur, welche die LibraryID enthält
libID .i ;und alle Prototype-Funktionen
plugin_init .proto_init
plugin_eventgadget .proto_eventgadget
EndStructure
NewList plugins.plugins_structure() ;Liste aller Plugins
Define PS_PluginDirectoryID = ExamineDirectory(#PB_Any, PS_PluginPath, "*.dll") ;Pluginordner durchkämmen und jede DLL laden
While NextDirectoryEntry(PS_PluginDirectoryID)
AddElement(plugins())
With plugins()
\libID = OpenLibrary(#PB_Any, PS_PluginPath + DirectoryEntryName(PS_PluginDirectoryID)) ;DLLs laden und Funktionen mit
\plugin_eventgadget = GetFunction(\libID, "plugin_eventgadget") ;Prototype in die Struktur speichern
\plugin_init = GetFunction(\libID, "plugin_init")
EndWith
Wend
Main_WindowID = OpenWindow(#PB_Any , 0, 0, 400, 300, "plugin test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ForEach plugins()
plugins()\plugin_init(WindowID(Main_WindowID)) ;Init-Funktion aller Plugins aufrufen.
Next
Repeat
WindowEvent = WaitWindowEvent(20)
Select WindowEvent
Case #PB_Event_Gadget
EventGadget = EventGadget()
Select EventGadget
Case -900 ;Irgendeinen Unsinn, damit "Default" funktioniert
Debug "..."
Default
ForEach plugins() ;EventGadget an alle Plugins weiterleiten, die selbst überprüfen,
plugins()\plugin_eventgadget(EventGadget) ;ob das EventGadget zum Plugin gehört
Next
EndSelect
EndSelect
Until WindowEvent = #PB_Event_CloseWindow
End
Code: Alles auswählen
;test.dll
Define button.i
ProcedureDLL plugin_init(hWnd.i)
Shared button
UseGadgetList(hWnd) ;Vom Hauptprogramm mitgeteilte GadgetList verwenden (Fenster oder auch ContainerGadget etc...)
button = ButtonGadget(#PB_Any, 0, 0, 100, 20, "Plugin")
EndProcedure
ProcedureDLL plugin_eventgadget(eventgadget.i)
Shared button
If eventgadget = button ;Das Plugin überprüft selbst, ob das EventGadget ein eigenes ist und führt entsprechend Code aus.
MessageRequester("Plugin","Button pushed")
EndIf
EndProcedure
Aber ist ja nur ein kleines Beispiel

Re: PB DLL als Modul im Hauptcode
Eine DLL ist kein eigenständiges Programm, sie läuft im Context des aufrufenden Prozesses und hat in diesem Sinne Kenntnis vom Programm. Und natürlich kann man auch auf Variablen des Hauptprogramms zugreifen ohne Shared Memory. Die DLL läuft sowieso im gleichen Prozessspeicher. Allerdings kann man das nicht direkt, da der Compiler den Namen keine Adressen zuordnen kann. Der gängige Weg ist es eine initialisierungsprozedur in der DLL zu haben, welche einen Pointer auf eine Datenstruktur erwartet, welche eben die globalen Variablen enthält. Kann auch Pointer auf Prozeduren vom Hauptprogramm enthalten, welche die DLL dann ausführen kann.
Hier habe ich so ein Plugin System mit DLL's realisiert: http://www.purebasic.fr/german/viewtopi ... 0&p=233466
Ist extrem simpel aufgebaut, du wirst es etwas komplexer benötigen aber da siehst du wie du auf Variablen und Prozeduren zugreifen kannst.
Hier habe ich so ein Plugin System mit DLL's realisiert: http://www.purebasic.fr/german/viewtopi ... 0&p=233466
Ist extrem simpel aufgebaut, du wirst es etwas komplexer benötigen aber da siehst du wie du auf Variablen und Prozeduren zugreifen kannst.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.
Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke!
Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke!

Re: PB DLL als Modul im Hauptcode
Ja und Nein. Prozess und DLL können zwar auf den jeweils anderen zugreifen,
haben aber in erster Linie keine Kenntnis davon. Deswegen das "eigenständige
Programm". Erst wenn man über Prozeduren einen Datenaustausch macht, dass
heißt die Zeiger überträgt, haben beide Kentniss davon. Aber das heißt noch
lange nicht, dass man im jeweils anderen Speicherbereich munter rumschreiben
und ihn verändern darf. Erst reicht wenn man die eigenen internen Verwaltungen
von PB bedengt. Lesen ist allerdings in keinem Fall ein Problem. Natürlich so
lange der Speicherbereich auch gültig ist. Der Prozess kann logischer weise nicht
in Speicher der DLL lesen, wenn die DLL diesen bereits freigegeben hat.
Es ist aber zu lange her, als das ich näher ins Detail gehen will und am Ende doch
was falsches sag, deswegen hab ich mich bisher so kurz gehalten
Sicher bin ich mir nur noch darinn, dass ich einige Stolperfallen umschiffen musste.
Ach ja ... damit sollte man sich auch nur beschäftigen, wenn man sicher mit
Zeigern umgehen kann.
MFG PMV
haben aber in erster Linie keine Kenntnis davon. Deswegen das "eigenständige
Programm". Erst wenn man über Prozeduren einen Datenaustausch macht, dass
heißt die Zeiger überträgt, haben beide Kentniss davon. Aber das heißt noch
lange nicht, dass man im jeweils anderen Speicherbereich munter rumschreiben
und ihn verändern darf. Erst reicht wenn man die eigenen internen Verwaltungen
von PB bedengt. Lesen ist allerdings in keinem Fall ein Problem. Natürlich so
lange der Speicherbereich auch gültig ist. Der Prozess kann logischer weise nicht
in Speicher der DLL lesen, wenn die DLL diesen bereits freigegeben hat.
Es ist aber zu lange her, als das ich näher ins Detail gehen will und am Ende doch
was falsches sag, deswegen hab ich mich bisher so kurz gehalten

Sicher bin ich mir nur noch darinn, dass ich einige Stolperfallen umschiffen musste.

Ach ja ... damit sollte man sich auch nur beschäftigen, wenn man sicher mit
Zeigern umgehen kann.

MFG PMV
Re: PB DLL als Modul im Hauptcode
Moin,
in aller Kürze:
Der Vorteil einer DLL besteht darin, das man sie in mehreren Programmen nutzen kann und nur einmal Speicher verbraucht, da man nicht statisch ins Programm linkt. Falls du das ganze nur in diesem einen Programm benötigst, nehme einen Include und linke lieber statisch.
Gerade bei solchen Dingen wie einer DLL (allerdings auch generell bei Includes etc) sollte man ein sehr genaues Interface deklarieren, sodass die DLL und der Hauptprogrammcode über eine vereinheitlichte Schnittstelle kommunzieren können. Hierfür bieten sich Datenstrukturen und Konstanten als Rückgabewert und Parameter an. Denn was bringt letztendlich eine DLL wenn sie den Programmcode der sie aufruft kennen muss. Das wiederspricht sich. Lese dir falls möglich mal was zum Konzept der Modularisierung und was zum Schichtenmodell durch.
Auf globale Variablen sollte man so wie es irgendwie machen lässt verzichten. (Zumindest Includeübergreifend, denn nur durch Kapselung lässt sich optimale austauschbarkeit und reusability garantieren)
Hoffe das hilft dir weiter. Hätte noch mehr geschrieben aber ich habe leider gerade wenig Zeit.
MfG
125
in aller Kürze:
Der Vorteil einer DLL besteht darin, das man sie in mehreren Programmen nutzen kann und nur einmal Speicher verbraucht, da man nicht statisch ins Programm linkt. Falls du das ganze nur in diesem einen Programm benötigst, nehme einen Include und linke lieber statisch.
Gerade bei solchen Dingen wie einer DLL (allerdings auch generell bei Includes etc) sollte man ein sehr genaues Interface deklarieren, sodass die DLL und der Hauptprogrammcode über eine vereinheitlichte Schnittstelle kommunzieren können. Hierfür bieten sich Datenstrukturen und Konstanten als Rückgabewert und Parameter an. Denn was bringt letztendlich eine DLL wenn sie den Programmcode der sie aufruft kennen muss. Das wiederspricht sich. Lese dir falls möglich mal was zum Konzept der Modularisierung und was zum Schichtenmodell durch.
Auf globale Variablen sollte man so wie es irgendwie machen lässt verzichten. (Zumindest Includeübergreifend, denn nur durch Kapselung lässt sich optimale austauschbarkeit und reusability garantieren)
Hoffe das hilft dir weiter. Hätte noch mehr geschrieben aber ich habe leider gerade wenig Zeit.

MfG
125


- tft
- Beiträge: 650
- Registriert: 08.09.2004 20:18
- Computerausstattung: GFX 3060 Ti , i7 12700F , 32 GB Ram , 900 GB SSD , TV
- Wohnort: Dachsen
- Kontaktdaten:
Re: PB DLL als Modul im Hauptcode
Hallo,
Ich bin mir da nicht sicher,aber in der Version 1.01 von PB gab es mal die Möglichkeit mit der VarImport / Export Directive der Dll Variablen Namen bekannt zu geben. Das funktionierte aber nur mit PB. Andere Programme konnten diese speziellen Dll Dateien nicht verwenden da sie nicht dem Standard entsprach. Das war sehr nützlich. Es liessen sich Programmteile zur Laufzeit austauschen. Fileicht weis einer der Spezis hir ob das noch geht.
Gruß TFT
Ich bin mir da nicht sicher,aber in der Version 1.01 von PB gab es mal die Möglichkeit mit der VarImport / Export Directive der Dll Variablen Namen bekannt zu geben. Das funktionierte aber nur mit PB. Andere Programme konnten diese speziellen Dll Dateien nicht verwenden da sie nicht dem Standard entsprach. Das war sehr nützlich. Es liessen sich Programmteile zur Laufzeit austauschen. Fileicht weis einer der Spezis hir ob das noch geht.
Gruß TFT
TFT seid 1989 , Turgut Frank Temucin , CH-Dachsen/DE-Berlin/TR-Antalya
Mein Projekt (Driving School Evergarden)
Codes bei (GitHub) Videos von (YouTube)
Treffen via Discord: Einladung
PB 6.10 | W11 | i7 12700F | 32 GB Ram | RTX 3060 Ti | 60 Herz -TV FullHD
ARDUINO Freak | Sprecher | Game Dev. | Geschichten Erzähler
Mein Projekt (Driving School Evergarden)
Codes bei (GitHub) Videos von (YouTube)
Treffen via Discord: Einladung
PB 6.10 | W11 | i7 12700F | 32 GB Ram | RTX 3060 Ti | 60 Herz -TV FullHD
ARDUINO Freak | Sprecher | Game Dev. | Geschichten Erzähler
