Hot Reload DLL [Windows]

Share your advanced PureBasic knowledge/code with the community.
User avatar
Mijikai
Addict
Addict
Posts: 1520
Joined: Sun Sep 11, 2016 2:17 pm

Hot Reload DLL [Windows]

Post by Mijikai »

Hot Reload DLL
Recompile libraries and see changes on the fly
without closing and restarting the host program.

Include:

Code: Select all

EnableExplicit

;Hot Reload DLL
;Platform: Windows OS
;Author: Mijikai
;Version: Draft 1

;It works with a copy of the original library (which is created) either in the same or temp directory.
;The original libraries creation time is monitored to determine if it should be reloaded.

;Functions:
;- hrdLibrary()   to add libraries
;- hrdFunction()  to determine the function address within a library
;- hrdReload()    checks all added libraries and reloads them if needed

;Callback (Init function called when a library is loaded/reloaded):

;Procedure.i Callback(*Name.String,Handle.i,*Parameter)
;EndProcedure

Structure HOT_RELOAD_DLL
  handle.i
  name.s
  copy.s
  date.FILETIME
  *init
  *parameter
EndStructure

Global NewList hrd.HOT_RELOAD_DLL()

Procedure.i hrdReload()
  Protected wfa.WIN32_FILE_ATTRIBUTE_DATA
  Protected *str
  Protected error.i
  ForEach hrd()
    If GetFileAttributesEx_(hrd()\name,#Null,@wfa)
      If CompareMemory(@hrd()\date,@wfa\ftCreationTime,SizeOf(FILETIME)) = #Null
        CopyMemory(@wfa\ftCreationTime,@hrd()\date,SizeOf(FILETIME))
        If hrd()\handle
          FreeLibrary_(hrd()\handle)
          DeleteFile(hrd()\copy)
          hrd()\handle = #Null
        EndIf
        If CopyFile(hrd()\name,hrd()\copy)
          hrd()\handle = LoadLibrary_(hrd()\copy)
        EndIf
        If hrd()\handle
          *str = @hrd()\name
          CallFunctionFast(hrd()\init,@*str,hrd()\handle,hrd()\parameter)  
        Else
          error = #True
          Break
        EndIf
      EndIf  
    Else
      error = #True
      Break
    EndIf
  Next
  ProcedureReturn error
EndProcedure

Procedure.i hrdLibrary(Library.s,*Init,Temp.i = #False,*Parameter = #Null)
  Protected *hrd.HOT_RELOAD_DLL
  If Library And *Init
    If AddElement(hrd())
      hrd()\name = Library
      hrd()\copy = "hrd_" + Library
      If Temp
        hrd()\copy = GetTemporaryDirectory() + hrd()\copy
      EndIf
      hrd()\init = *Init
      hrd()\parameter = *Parameter
      *hrd = @hrd()
      If hrdReload() = #Null
        ProcedureReturn *hrd\handle
      EndIf
    EndIf
  EndIf
  ProcedureReturn #Null
EndProcedure

Procedure.i hrdFunction(Handle.i,Name.s)
  Protected *name.Ascii
  Protected *address
  *name = Ascii(Name)
  If *name
    *address = GetProcAddress_(Handle,*name)
    FreeMemory(*name)
  EndIf
  ProcedureReturn *address
EndProcedure
Example Program:

Code: Select all

EnableExplicit

XIncludeFile "hrd.pbi"

Global *hot;<- holds a function pointer (gets updated by the callback)

Procedure.i Init(*Name.String,Handle.i,*Parameter);<- callback used to update data/pointers
  *hot = hrdFunction(Handle,"Dummy")
  ProcedureReturn #Null
EndProcedure

Procedure.i Main()
  hrdLibrary("hot.dll",@Init());<- example dll
  If OpenWindow(0,#Null,#Null,200,100,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    ButtonGadget(1,20,30,160,30,"Test")
    Repeat
      If hrdReload();<- check if there where changes made to the library
        Break  
      EndIf
      Select WaitWindowEvent()
        Case #PB_Event_Gadget
          If EventGadget() = 1 And *hot
            CallFunctionFast(*hot)
          EndIf
        Case #PB_Event_CloseWindow
          Break
      EndSelect
    ForEver
    CloseWindow(0)
  EndIf
  ProcedureReturn #Null
EndProcedure

End Main()
Example DLL (compile in the same directory as the example program):

Code: Select all

EnableExplicit

ProcedureDLL.i Dummy()
  MessageRequester("Message","Message :)")
  ProcedureReturn #Null
EndProcedure
User avatar
chi
Addict
Addict
Posts: 1087
Joined: Sat May 05, 2007 5:31 pm
Location: Austria

Re: Hot Reload DLL [Windows]

Post by chi »

Thanks for sharing, works great! Could be useful for a music visualizer ;)
Et cetera is my worst enemy
User avatar
idle
Always Here
Always Here
Posts: 5891
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Hot Reload DLL [Windows]

Post by idle »

Great way to do updates and hot plug a dll. :mrgreen:
Fred
Administrator
Administrator
Posts: 18207
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Hot Reload DLL [Windows]

Post by Fred »

I didn't know it was possible on Windows !
User avatar
Caronte3D
Addict
Addict
Posts: 1361
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: Hot Reload DLL [Windows]

Post by Caronte3D »

Awesome :shock:
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Hot Reload DLL [Windows]

Post by Kwai chang caine »

Very nice thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
Post Reply