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)
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
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
