Library-System for .DLLs, and .so

Share your advanced PureBasic knowledge/code with the community.
jamirokwai
Enthusiast
Enthusiast
Posts: 771
Joined: Tue May 20, 2008 2:12 am
Location: Cologne, Germany
Contact:

Library-System for .DLLs, and .so

Post by jamirokwai »

Hi there,

while fiddling around with this http://www.purebasic.fr/english/viewtop ... 19&t=54507, I reworked my approach to a Plugin-System.
I had it working in my audiosynth (which is far from being usable)...

You have to compile the dll or .so (Mac OS X) first, the run library.pb.

plugin.pb, compile to testlib.dll or testlib.so

Code: Select all

; ##############
; # PB_Library #
; # Ver. 1.0.0 #
; ##############
; # OS X, Win  #
; ##############

; Plugin for PB-Libraries
; (c) 2011-2013, Jörg Burbach (http://www.joerg-burbach.de), use as you like, give changes back, and credit - please
; Compile to .dll, .so
; Do not use Threads, or Unicode!

EnableExplicit

Global NewMap Settings.s()

; Do all the Magic here
ProcedureCDLL.q DoMagic(MagicToken.s)
  Protected result.s
  result = MagicToken + ", " + Settings("position")
  ProcedureReturn @result  
EndProcedure

; set and get Parameters
ProcedureCDLL.q DoSettings(args.s,value.s)
  Settings(args) = value
EndProcedure

ProcedureCDLL.s GetSettings(args.s)
  ProcedureReturn Settings(args)
EndProcedure

; Return Icon
ProcedureCDLL.q GetIcon()
 ProcedureReturn ?Icon
EndProcedure

; Return Plugin-Name
ProcedureCDLL.s GetName()
 ProcedureReturn PeekS(?Name)
EndProcedure

; Return Copyright-Notice
ProcedureCDLL.s GetCopyright()
 ProcedureReturn PeekS(?Copy)
EndProcedure

; Return Description
ProcedureCDLL.s GetDesc()
 ProcedureReturn PeekS(?Desc)
EndProcedure

; Return Creator
ProcedureCDLL.s GetCreator()
 ProcedureReturn PeekS(?Crea)
EndProcedure

; Return Version
ProcedureCDLL.s GetVersion()
 ProcedureReturn PeekS(?Vers)
EndProcedure

; Init Plugin (allocate memory, load defaults)
ProcedureCDLL.q Init()
  Settings("position") = "World"
EndProcedure

; Exit Plugin (free memory, save data)
ProcedureCDLL   DeInit()
  FreeMap(Settings())
EndProcedure

DataSection
  
  Name: Data.s "Test-Plugin"                      ; Plugin-Name
  Vers: Data.s "1.0.0"                            ; Plugin-Version
  Desc: Data.s "Test-Plugin, just to test..."     ; Description
  Copy: Data.s "(c,p) 2010-2013 quadWorks"        ; Copyright-Notice
  Crea: Data.s "quadWorks"                        ; Creator
  Icon: ; PNG, BMP, whatever
    ; size : 329 bytes - made with Bin2Data
    Data.q $0A1A0A0D474E5089,$524448490D000000,$1000000010000000,$0F2D280000000308,$4D41670400000053
    Data.q $DAB2DC04D9000041,$544C507E00000002,$F8F0F8F8FFFFFF45,$F0F0E8F0F0F0F0F0,$E0D8F0E8E0F0E8E8
    Data.q $C8F0D8D0F8D8D0F0,$F0D0C0F0D0C8F0D8,$C0B0F0C8B8F0C8C0,$98F0B8A0F8B8A0F0,$F8A888F8B098F8B8
    Data.q $9878F8A078F8A080,$68F89870787878F8,$F88858F89060F890,$3840F88048F88050,$28F86830F8703838
    Data.q $F86020F86028F868,$5010F85818F86018,$A5F84808F85008F8,$49760000002EAD7F,$518F949C78544144
    Data.q $1825EF840830800B,$0F658311C0C462C1,$EA0832D83FFFFDD2,$2B44F453F07D0EA9,$2B033E543C14350F
    Data.q $55621A60E8B00CC8,$E66CDD509F40D318,$43BD0B039B4965C8,$E840AF413D7349B1,$4C210884D74B415E
    Data.q $F7310D99041D1958,$65F847DBE59F72E5,$0000719E576FDFDD,$0C9B0C0003FFFF00,$0000007E4B7209FD
    Data.q $6042AE444E454900
    Data.b $82
EndDataSection
library.pb

Code: Select all

; ##############
; # PB_Library #
; # Ver. 1.0.0 #
; ##############
; # OS X, Win  #
; ##############

; (c) 2011-2013, Jörg Burbach (http://www.joerg-burbach.de), use as you like, give changes back, and credit - please
; this code will add library-support to your Software.
; Just add this include, and call the functions.
; The Magic is applied in your dll, the result comes in form of a string

#demo = 1 ; set to 0, if used as library

Structure PlugIn_Struct
  Handle.q        ; Handle, for function
  buffer.q        ; Memory for Buffering, Input, and Output
  Init.q          ; DLL init
  DeInit.q        ; DLL Clean up
  GetIcon.q       ; Get Icon (PNG)
  GetName.q       ; Name of Plug-In
  GetVersion.q    ; Version of Plugin
  GetCopyright.q  ; Copyright
  GetDesc.q       ; Description
  GetCreator.q    ; Name of Creator
  DoMagic.q       ; Function to call
  DoSettings.q    ; Set Configuration
  GetSettings.q   ; Get Configuration
  Name.s          ; Self-referencing Name
EndStructure

Global NewMap Plugins.Plugin_Struct()

Procedure.q Library_OpenPlugin(Map MyPlugin.PlugIn_Struct(),Name.s,FileName.s)
  If FileSize(FileName) < 0
    Debug "Library not found: " + FileName
    ProcedureReturn 
  EndIf
  
  With MyPlugIn(Name)
    \Handle       = OpenLibrary(#PB_Any, FileName)
    If IsLibrary(\Handle)
      \Name         = Name
      \Init         = GetFunction(\Handle,"Init")
      \DeInit       = GetFunction(\Handle,"DeInit")
      \GetIcon      = GetFunction(\Handle,"GetIcon")
      \GetName      = GetFunction(\Handle,"GetName") 
      \GetCopyright = GetFunction(\Handle,"GetCopyright") 
      \GetDesc      = GetFunction(\Handle,"GetDesc") 
      \GetCreator   = GetFunction(\Handle,"GetCreator")
      \GetVersion   = GetFunction(\Handle,"GetVersion")
      \DoMagic      = GetFunction(\Handle,"DoMagic")
      \DoSettings   = GetFunction(\Handle,"DoSettings")
      \GetSettings  = GetFunction(\Handle,"GetSettings")
      \buffer       = CallCFunctionFast(\Init)    
      Debug "Library loaded: " + FileName + ", ID " + Name
      ProcedureReturn \Handle
    EndIf
  EndWith
EndProcedure

Procedure   Library_FreePlugin(Map MyPlugin.PlugIn_Struct(),Name.s)
  If MyPlugIn(Name)\Handle <> 0
    If IsLibrary(MyPlugIn(Name)\Handle)
      If MyPlugIn(Name)\DeInit <> 0
        CallCFunctionFast(MyPlugIn(Name)\DeInit)
      EndIf
      DeleteMapElement(MyPlugIn(),Name)
      Debug "Library removed : " + Name
    EndIf
  EndIf
EndProcedure

Procedure.s Library_GetName(*Plugin.PlugIn_Struct)
  If *PlugIn\GetName <> 0
    ProcedureReturn PeekS(CallCFunctionFast(*PlugIn\GetName))
  EndIf
EndProcedure

Procedure.s Library_GetCopyright(*Plugin.PlugIn_Struct)
  If *PlugIn\GetCopyright <> 0
    ProcedureReturn PeekS(CallCFunctionFast(*PlugIn\GetCopyright))
  EndIf
EndProcedure

Procedure.s Library_GetDesc(*Plugin.PlugIn_Struct)
  If *PlugIn\GetDesc <> 0
    ProcedureReturn PeekS(CallCFunctionFast(*PlugIn\GetDesc)) 
  EndIf
EndProcedure

Procedure.s Library_GetVersion(*Plugin.PlugIn_Struct)
  If *PlugIn\GetVersion <> 0
    ProcedureReturn PeekS(CallCFunctionFast(*PlugIn\GetVersion)) 
  EndIf
EndProcedure

Procedure.q Library_GetIcon(*Plugin.PlugIn_Struct)
  If *PlugIn\GetIcon <> 0
    ProcedureReturn CatchImage(#PB_Any,CallCFunctionFast(*PlugIn\GetIcon))
  EndIf
EndProcedure

Procedure.s Library_GetCreator(*Plugin.PlugIn_Struct)
  If *PlugIn\GetCreator <> 0
    ProcedureReturn PeekS(CallCFunctionFast(*PlugIn\GetCreator)) 
  EndIf
EndProcedure

Procedure.s Library_GetField(args.s,feld.s)
  Protected position,leng
  
  position = FindString(args,feld + ":") + Len(feld) + 1
  leng = FindString(args,"|",position)
  
  If Position <> 5
    ProcedureReturn Mid(args,position,leng-position)
  EndIf  
EndProcedure

Procedure.s Library_DoMagic_String(*Plugin.PlugIn_Struct,Command.s)
  ProcedureReturn PeekS(CallCFunctionFast(*Plugin\DoMagic,@Command))
EndProcedure

Procedure   Library_DoSettings(*Plugin.PlugIn_Struct,args.s,value.s)
  CallCFunctionFast(*Plugin\DoSettings,@args,@value)
EndProcedure

Procedure.s Library_GetSettings(*Plugin.PlugIn_Struct,args.s)
  ProcedureReturn PeekS(CallCFunctionFast(*Plugin\GetSettings,@args))
EndProcedure

; The paths work fine for windows.
; you will need to edit or determine the correct paths for OS X
CompilerIf #demo = 1
  Debug Library_OpenPlugin(Plugins(),"0","test.dll") 
  Debug Library_GetName(Plugins("0"))

  UsePNGImageDecoder()
  x = Library_GetIcon(Plugins("0"))
  SaveImage(x,"test.bmp")
 
  Debug Library_DoMagic_String(Plugins("0"),"Hallo")
  Debug "Current Word: " + Library_GetSettings(Plugins("0"),"position")

  Library_DoSettings(Plugins("0"),"position","Earth") 
  Debug "Current Word: " + Library_GetSettings(Plugins("0"),"position")
  Debug Library_DoMagic_String(Plugins("0"),"Hallo")

  Debug Library_FreePlugin(Plugins(),"0")
compilerendif
Regards,
JamiroKwai