Version 0 of dllfix

Updated 2009-12-06 00:06:22 by hat0

This package is useful in cases where you're making a Starkit for a windows-based machine, and your starkit relies on a DLL which in turn relies on other DLLs (e.g. the brick engine dll depends on several SDL dlls in order to function). It copies any DLLs you specify out into a temporary directory and adds that directory to the DLL search path.

Use it thus:

::dllfix::setup name source-dll-directory list-of-dlls

The "name" argument is used as the prefix for the temporary directory. The source dll directory is a path to where the DLLs are stored. The list of dlls is a list of dlls.

If you feel like removing the temp directory, you can call ::dllfix::cleanup to do so.

hat0


#
# Copy dependent dlls out to env(temp) and use ffidl to set them to load
# first in the DLL search path
#
package require ffidl

ffidl::callout add_dir_to_dll_search_path {pointer-utf8} int [ffidl::symbol kernel32.dll SetDllDirectoryA]



namespace eval ::dllfix {
  namespace export setup cleanup

  set dlls {}
  set dllpath {}
}


#
# takes a source and a list of DLLs to copy
#
proc ::dllfix::setup { name src dll_list } {

   global env
   variable dlls
   variable dllpath

   # make a probably-unique temp directory for the dlls
   set dllpath [file join $env(temp) $name-[clock seconds]]
   if { [catch {file mkdir $dllpath} err] } {
      return $err
   }

   # copy the DLLs
   foreach dll $dll_list {

      # try to copy ..
      if { [catch {file copy -force [file join $src $dll] $dllpath} err] } {

         # error?  clean up any already-copied DLLs and return the error
         ::dllfix::cleanup
         return $err

      }

      # copied?  append to the cleanup list
      lappend dlls $dll

   }

   # and add the dll path to the search path
   add_dir_to_dll_search_path $dllpath

}


#
# remove any DLLs we've copied into env(temp)
#
proc ::dllfix::cleanup {} {

   variable dlls
   variable dllpath

   # remove ..
   file delete $dllpath

   # and empty the list
   set dlls {}

}

package provide dllfix [lindex {Revision: 0.1} 1]