Program with plugins

Just starting out? Need help? Post your questions and find answers here.
AZJIO
Addict
Addict
Posts: 1318
Joined: Sun May 14, 2017 1:48 am

Program with plugins

Post by AZJIO »

How to write a plugin-enabled program? Interested in Scintilla. I need cross platform.
1. Search for dll in the plugins folder and check if it matches.
2. The plugin adds its commands to the main menu in the plugins section. That is, attaching the menu to the main menu.
3. Plugin events must be embedded in the main loop.
That is, I have to execute a function in the dll to pass a pointer to a structure with data about the window and Scintilla, thereby making access to the shared object.
Has anyone already tried it?
benubi
Enthusiast
Enthusiast
Posts: 113
Joined: Tue Mar 29, 2005 4:01 pm

Re: Program with plugins

Post by benubi »

I personally haven't written a system that was error-free and flexible enough to realize all that, but I had very similar ideas in mind.

I came up with the Idea but never done this:

- Use Runtime library extensively
- When opening the DLL, search for a specific function e.g. init_app_plugin() and give it a pointer to a simple Interface to access/exchange "Runtime" variables between App and Plugin
- You would also have an interface on the App's side, probably.

Perhaps the init_app_plugin() could look like that, but this may be already too complicated?

Code: Select all

Prototype.i init_app_plugin(*ToPluginInterfacePointer, *FromPluginInterfacePointer, *CheckValuesFromApp, *CheckValuesFromPlugin)
You could then use the "simple" interfaces to exchange pointers to more data/functions in both ways; you could also implement the event-queue access for the plug-in.

The *CheckValues could be additional values you check for compatibility or versions or maybe licenses or something IDK.

The interfaces would need some registration mechanism abstraction layer to bind the two Runtime name spaces and object areas, and Dialogs created in the Plugin or App can only use callbacks from their own name-space. So maybe the Interfaces would also include enumeration procedures for available dialogs, menus etc. You could also create the menu items using an XML configuration file for each plugin & customize the Application or Plugin's behavior more flexibly and perhaps save some more complicated hard-code programming going this way (maybe).
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Program with plugins

Post by mk-soft »

The problem is that a DLL has its own PB object management and therefore the access from the DLL to the PB objects of the main program does not work directly.
But we had already had this once in the forum (and found it again).
I'll have to have a look at how this looks with the menus and events.

Here is a basis for the transfer of the PB object management to the DLL and what is important the release.
Link: Access gadgets from library (All OS)
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
AZJIO
Addict
Addict
Posts: 1318
Joined: Sun May 14, 2017 1:48 am

Re: Program with plugins

Post by AZJIO »

How do I get the array created in the DLL and passed as a "*FArray" pointer so that I can access the elements of the array.
See Notepad++ plugin_template.pb
I want to make Notepad++ plugins work with my Scintilla object.

I was able to access

Code: Select all

; DLL
Global Dim FuncsArray.FuncItem(2)
With FuncsArray(0)
	\_itemName = "item 1"
	\_pFunc = @item1()
	\_pShortcutKey = AllocateStructure(ShortcutKey)
	\_pShortcutKey\_isCtrl = #True
	\_pShortcutKey\_isShift = #True
	\_pShortcutKey\_isAlt = #True
	\_pShortcutKey\_key = #VK_NEXT
EndWith
With FuncsArray(1)
	\_itemName = "item 2"
	\_pFunc = @item2()
EndWith

ProcedureCDLL.i getFuncsArray(*FuncsArraySize.Integer)
	*FuncsArraySize\i = ArraySize(FuncsArray())
	ProcedureReturn @FuncsArray()
EndProcedure
Program

Code: Select all

Structure ShortcutKey Align #PB_Structure_AlignC
	_isCtrl.b
	_isAlt.b
	_isShift.b
	_key.b
EndStructure

Structure FuncItem Align #PB_Structure_AlignC
	_itemName.s{64}
	*_pFunc
	_cmdID.l
	_init2Check.b
	*_pShortcutKey.ShortcutKey
EndStructure

Structure LibPlugin
	fname.s
	path.s
	pname.s{64}
	id.i
	FuncsArraySize.i
	*FuncsArray
	Array FuncsArray1.FuncItem(0)
; 	List FuncsArray1.FuncItem()
	
EndStructure

; Procedure GetArr(Array *FArray.FuncItem(1), Array *FArray2.FuncItem(1))
; 	CopyArray(*FArray() , *FArray2())
; EndProcedure

Procedure GetPlugin(LastItem)
	Protected i, tmp$
	Protected NewList LDirName.LibPlugin()
	Protected *FuncsArraySize.Integer
	Protected *FArray
	Protected *pname
	Protected *FuncItem0.FuncItem
	If ExamineDirectory(0, PathConfig$ + "Plugins\", "*") 
		While NextDirectoryEntry(0)			  
			If DirectoryEntryType(0) = #PB_DirectoryEntry_Directory
				If DirectoryEntryName(0) = "." Or DirectoryEntryName(0) = ".."
					Continue
				EndIf
				tmp$ = PathConfig$ + "Plugins\" + DirectoryEntryName(0) + "\" + DirectoryEntryName(0) + ".dll"
				If FileSize(tmp$) And AddElement(LDirName())
					LDirName()\fname = DirectoryEntryName(0)
					LDirName()\path = tmp$
				EndIf
			EndIf
		Wend
		FinishDirectory(0) 
	EndIf
	If ListSize(LDirName())
		ForEach LDirName()
			LDirName()\id = OpenLibrary(#PB_Any, LDirName()\path)
			If Not LDirName()\id
				Continue
			EndIf
			*pname = CallFunction(LDirName()\id, "getName")
			LDirName()\pname = PeekS(*pname)
			*FArray = CallFunction(LDirName()\id, "getFuncsArray", @*FuncsArraySize)
			Debug *FuncsArraySize
			LDirName()\FuncsArraySize = *FuncsArraySize - 1
	; 		GetArr(*FArray, LDirName()\FuncsArray1(0))
			ReDim LDirName()\FuncsArray1(LDirName()\FuncsArraySize)
			For i = 0 To LDirName()\FuncsArraySize
				*FuncItem0 = *FArray + i * SizeOf(FuncItem)
	; 			LDirName()\FuncsArray1(i)
				CopyStructure(*FuncItem0, LDirName()\FuncsArray1(i), FuncItem)
			Next
	; 		LDirName()\FuncsArray1(0) = *FArray
			For i = 0 To LDirName()\FuncsArraySize
				Debug LDirName()\FuncsArray1(i)\_itemName
			Next
		Next
	EndIf
EndProcedure
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Program with plugins

Post by mk-soft »

Here you won't get anywhere with arrays (dim). So it is better to work with structure array with unknown size. Also, passing a string with a static size is more likely to avoid memory leaks.

Since I don't know your structure another example

Code: Select all


Structure udtItem
  Name.s{64} ; Static String
  *Function
  ; ...
EndStructure

Structure udtItemArray
  ; Header
  Size.i
  ItemCount.i
  ; Items
  Item.udtItem[0]
EndStructure


Procedure fc()
  ;
EndProcedure

; Allocate 2 Items

*mem.udtItemArray = AllocateMemory(2 * SizeOf(udtItem) + SizeOf(udtItemArray))

*mem\Size = MemorySize(*mem)
*mem\ItemCount = 2
*mem\Item[0]\Name = "Item 1"
*mem\Item[0]\Function = @Fc()

*mem\Item[1]\Name = "Item 2"
*mem\Item[1]\Function = @Fc()

CallDebugger
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
AZJIO
Addict
Addict
Posts: 1318
Joined: Sun May 14, 2017 1:48 am

Re: Program with plugins

Post by AZJIO »

When I close the application, I get the error: "The application being debugged terminated unexpectedly". I am testing a plugin for Linux. After the line CloseLibrary(#PB_All) I get no response from "Debug 4"

Code: Select all

CloseLibrary(#PB_All)
Debug 4
Why is my AttachProcess() function running on Linux? The description says that this function only works on Windows when opening a DLL (OpenLibrary).

You can get the full source here: viewtopic.php?t=80580
My_Notepad_Sci (LinPlug).pb
plugin_For_My_Notepad_Sci (Linux).pb
User avatar
HeX0R
Addict
Addict
Posts: 979
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

Re: Program with plugins

Post by HeX0R »

That might be related to that bug here?
Could you try with PB5.73?
AZJIO
Addict
Addict
Posts: 1318
Joined: Sun May 14, 2017 1:48 am

Re: Program with plugins

Post by AZJIO »

Hi HeX0R
Your code works for me in both cases. My code doesn't work in both cases.
AZJIO
Addict
Addict
Posts: 1318
Joined: Sun May 14, 2017 1:48 am

Re: Program with plugins

Post by AZJIO »

I found the reason for the error. If you remove all calls to the MessageRequester() function from the code in the SO file, the debugger returns all the information without breaking anywhere, and no error messages appear.

This is the code that caused the error. That is, you do not even need some complex code.

Code: Select all

Debug OpenLibrary(#PB_Any, "/home/user/Apps/Source/Plugins/Template/Template.so")
CloseLibrary(#PB_All)
GetClipboardText(), OpenWindow() - also throws an error
Post Reply