Some cool plugin structure

BlitzMax Forums/BlitzMax Programming/Some cool plugin structure

JoshK(Posted 2006) [#1]
Here's a plugin type. Notice it has a field for a function:
Type TPlugin
	Field name$
	Field library
	Field class
	Field GetClass:Int()	
EndType


Now here is the loading code. It loads the library and retrieves the handle to a function, then stores it as a field:
Function LoadPlugins:Int(path$)
	path=Replace(path,"/","\")
	If Right(path,1)<>"\" path=path+"\"
	dir=ReadDir(path)
	If Not dir Return
	Repeat
		file$=NextFile(dir)
		If file="" Exit
		If Lower(ExtractExt(file))="dll"
			programlog "Loading plugin "+quote(file)+"..."
			plugin:TPlugin=New TPlugin
			plugin.name=StripAll(file)
			plugin.library=LoadLibraryA(path+file$)
			If plugin.library
				plugin.GetClass=GetProcAddress(plugin.library,"PluginClass")
				If plugin.GetClass
					plugin.class=plugin.GetClass()
				EndIf
				FreeLibrary plugin.library
				plugin.library=0
			EndIf
		EndIf
	Forever
	Return True
EndFunction


I thought it was a pretty cool concept, and it works without a hitch in Max.


JoshK(Posted 2006) [#2]
Here's a more OO variation that loads the library and performs a function only when it is needed:
Type TPlugin
	Field name$
	Field file$
	Field classvalue
	Field GetClass:Int()

	Method Class:Int()
		Local library
		Select classvalue
			Case 0
				library=LoadLibraryA(file$)
				If library
					GetClass=GetProcAddress(library,"PluginClass")
					If GetClass
						classvalue=GetClass()
					EndIf
					GetClass=Null
					freelibrary library					
				EndIf
				If classvalue
					Return classvalue
				Else
					classvalue=-1
					Return 0
				EndIf
			Case -1
				Return 0
			Default
				Return classvalue
		EndSelect
	EndMethod

EndType



AlexO(Posted 2006) [#3]
interesting setup. Thanks for sharing :).


Perturbatio(Posted 2006) [#4]
nice :)

*EDIT*

can you get it to unloadlibrary as well?


skidracer(Posted 2006) [#5]
And for crossplatform support Apple and OSX usage can include the following, dunno about unloading :

Const RTLD_DL_SYMENT=1
Const RTLD_DL_LINKMAP=2

Const RTLD_LAZY=1 'Lazy Function call binding
Const RTLD_NOW=2 'Immediate Function call binding
Const RTLD_BINDING_MASK=3 ' Mask of binding time value
Const RTLD_NOLOAD=4 ' Do Not load the object.
Const RTLD_DEEPBIND=8 'Use deep binding
Const RTLD_LOCAL=0
Const RTLD_GLOBAL=$100
Const RTLD_NODELETE=$1000

Extern "C"
Function LoadLibraryA(libname$z,mode=RTLD_GLOBAL|RTLD_NOW)="dlopen"
Function GetProcAddress:Byte Ptr(libhandle,symbol$z)="dlsym"
End Extern



JoshK(Posted 2006) [#6]
Use FreeLibrary(HLib). You have to Extern it.


ImaginaryHuman(Posted 2006) [#7]
Cool, but slightly complicated. WOuld be nice to have plugin functionality *easily* as standard BlitzMax commands.