TIP #239: ENHANCE THE 'LOAD' COMMAND ====================================== Version: $Revision: 1.12 $ Author: Jeff Hobbs State: Draft Type: Project Tcl-Version: 8.7 Vote: Pending Created: Wednesday, 26 January 2005 URL: https://tip.tcl-lang.org239.html Post-History: ------------------------------------------------------------------------- ABSTRACT ========== This TIP proposes enhancing the Tcl *load* command with the ability to load arbitrary libraries and functions. RATIONALE =========== The current Tcl *load* command limits itself operating within the context of loading Tcl extension libraries and nothing else, even though all the code is there for general library loading. With the introduction of the VFS and more extensions having prerequisite library dependencies, the ability to load arbitrary libraries would ease development of StarKits with these extensions. It will also provide a general mechanism to assist other developers get around the difficult process of cross-platform library loading. SPECIFICATION =============== Current specification: *load* /fileName/ ?/packageName/ ?/interp/?? Recommended specification: *load* ?*-function* /funcName/? ?*-interp* /interp/? ?*-package* /packageName/? ?*-keeplibrary*? ?*--*? /fileName||libref/ returns library pointer reference value The *-interp* option takes the place of the optional final /interp/ argument. The *-package* option replaces the optional /packageName/ argument. The user specifies just the partial function name without the "_Init" or "_SafeInit", as before. The function is called with the Tcl interpreter to initialize as the sole argument. If this option is not specified, the name is inferred from the filename. If *-function* is specified, the Init call is not made. The *-function* option takes a C function name to find the symbol of (via dlsym(), GetProcAddress(), or related function). If *-function* is specified, *-call* and *-interp* are ignored and the return value is the pointer location to the function, or 0 if it is not found. When this is used, the library is not closed upon success, it remains open until a call to *unload* is made. The *-keeplibrary* option set a flag to indicate the library should not be unloaded by Tcl. This is needed in cases where the library may register functions (eg, via C's *atexit*) that are needed beyond the lifetime of Tcl finalization. This should only be used when necessary. An error is thrown if the library cannot be loaded, otherwise a library pointer reference value is returned (unless *-function* is used). *load* could take a library pointer reference as an argument for repeated *-function* requests. I will also recommend obsoleting the existing *unload* call to use this new functional spec style. Current spec, to be unsupported (it's new in 8.5): *unload* ?/switches/? /fileName/ ?/packageName/ ?/interp/?? New specification: *unload* ?*-interp* /interp/? ?*-package* /packageName/? ?*-keeplibrary*? ?*--*? /fileName||libref/ I removed the /-nocomplain/ option. The user should simply *catch* the command if they wish to suppress the types of errors that unload would throw. I think that C functions should be made available as well for cross-platform access to the load functionality, but that is not specified in this TIP. This would need to account for users that may configure Tcl with --disable-load (does anybody need that anymore?). DISCUSSION ============ Not all platforms may support library loading to a degree required for this TIP functionality. In that case, an error message will be thrown. The use of *--* as a option end switch was debated as unnecessary since there is only one fixed argument. JH likes the use of it for the completeness it gives the use of switches. The *load* command will determine the use of the new form by checking if more than one argument is given and the first argument starts with a *-*. This should not affect any existing extensions, as dynamic library filenames beginning with *-* are rare. Here is a reference to Perl's dynamic library loading functionality: EXAMPLES ========== For a package in a starkit, tls example with shared OpenSSL library shipped in package: # $dir set by package mechanism if {[package provide starkit] ne ""} { load -call {} $dir/libopenssl.so } load $dir/libtls1.5.so This would handle the extracting of dependent libraries in starkits automatically (and their subsequent disposal). Another example would be Oratcl 4.3's use of dynamic Oracle library callouts, which it has to do by hand due to the lack of this functionality in the core. REFERENCE IMPLEMENTATION ========================== [To be uploaded to SourceForge and URL added to this TIP.] COPYRIGHT =========== This document has been placed in the public domain. ------------------------------------------------------------------------- TIP AutoGenerator - written by Donal K. Fellows