Version 15 of unload

Updated 2014-11-30 18:34:09 by pooryorick
unload ?switches? fileName ?packageName? ?interp?

http://www.purl.org/tcl/home/man/tcl8.5/TclCmd/unload.htm

New command in Tcl 8.5 that can remove functionality imported via load (in some cases). See TIP 100 [L1 ] from George Petasis for where it came from.


Hints for extension authors who want to have an unloadable extension:

  • Be prepared for extra work when using a custom Tcl_Object type with non-NULL freeProc
  • Be extremly careful in your use of TSD (Thread Specific Data)
  • Be prepared for trouble if your extension involves the VFS layer
  • ...

JH: Note that TIP 239 [L2 ] will likely change the unload command before 8.5 is final.


RS 2007-10-19: Here's a simple working example of building a DLL with tcltcc, loading, calling, unloading it:

 #!/usr/bin/env tclsh85

 package require tcc 0.2
 set d [tcc::dll]
 $d ccode {static int fib(int n) {return n <= 2? 1 : fib(n-1) + fib(n-2);}}
 $d cproc fiboy {int n} int {return fib(n);}
 $d cproc hello {} char* {return "world";}
 $d ccode {
    DLL_EXPORT int Fiboy_Unload(Tcl_Interp* interp, int flags) {
        Tcl_DeleteCommand(interp,"fiboy");
        Tcl_DeleteCommand(interp,"hello");
        printf("bye, world! flags: %d\n", flags);
        return TCL_OK;
    }
 }
 $d write -name fiboy -code {Tcl_Eval(interp,"puts {hello Fiboy!}");}

 load fiboy[info sharedlibextension]
 puts "[fiboy 20] [hello]"

 unload fiboy[info sharedlibextension]
 catch {puts "[fiboy 20] [hello]"} res
 puts $res

which produces

 hello Fiboy!
 6765 world
 bye, world! flags: 2
 invalid command name "fiboy"

Only if a _Unload function is provided (_SafeUnload for safe interps) will unload succeed. Be careful to delete all commands the DLL created, otherwise get a seg fault.

Another observation: on Win XP at least (ActiveTcl 8.5b1), the load/unload order matters. Given foo.dll and bar.dll, the sequence

   load foo; load bar; unload foo; unload bar

segfaults, while

   load foo; load bar; unload bar; unload foo

succeeds. Is that so? The man page does not mention such a condition. Example:

 $ tclsh85
 % load test.dll
 DLL loaded
 % load fiboy.dll
 hello Fiboy!
 % unload test.dll
 DLL unloaded
 % unload fiboy.dll
 ---------------------------------------- seg fault popup --------------------------
 /etc/dk $

Then again, on Windows 95, 8.5b1 built myself with mingw, I can unload a pair of DLLs in any of the two orders... Funny.


kbk would like to revert TIP #100 because it doesn't really work. There are too many calls that retain pointers into the loaded library, e.g., Tcl_RegisterObjType, which can't be undone. (1)

References

1
kbk, Tcl Chatroom, 2014-11-24