TIP 239: Enhance the 'load' Command

Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2017 Conference, Houston/TX, US, Oct 16-20
Send your abstracts to tclconference@googlegroups.com
by Aug 21.
Author:         Jeff Hobbs <jeffh@activestate.com>
State:          Draft
Type:           Project
Vote:           Pending
Created:        26-Jan-2005
Post-History:   
Tcl-Version:    8.7

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:

http://aspn.activestate.com/ASPN/Perl/Products/ActivePerl/5.8/lib/DynaLoader.html

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.

History