Updated 2013-12-27 15:38:33 by pooryorick

load dynamically links a code library (typically written in C, C++, or some comparable language) with the program containing the Tcl interpreter. Most [extensions] use this mechanism.

See Also  edit

Tcl Extension: User Guide
[dlopen extension]
a small extension to open shared libraries that aren't Tcl extensions
ffidl
twapi
tcom / COMet
Tcl_InitStubs
info loaded
info sharedlibextension

Synopsis  edit

load fileName ?packageName? ?interp?

Documentation  edit

official reference
official reference: C API

Description  edit

If fileName does not contain any directory separators, the file will be searched for in OS-specific ways. If packageName is not provided, it is derived from the fileName by trimming certain prefixes and suffixes and applying capitalization rules (so /usr/local/lib/libfoobar.so would become Foobar); it is used to locate the name of the initialization function inside the library. If interp is not supplied, the library is initialized for the current interpreter.

Troubleshooting  edit

So what do you do when load, or, even more mysteriously, package, fails? There are many, many ways for this to happen, and typical built-in diagnostics from supplied loaders are inscrutable.

One handy tool for such situations is a dependency utility. Under Windows, DependencyWalker [1] walks dependencies. When you let it load a specific dll, it assists you in determining what other DLLs it needs.

AMG: I just had a very strange problem with load. When I screw up and try to call my command without loading the the package first, of course I get an error for the command, but I also get an error when trying to load the package. When I do things in the right order, everything works. Yeah I know, I shouldn't be trying to do things backwards, but I still wonder why the load fails.
[andy@toaster|~/e6b]$ tclsh
% atc::get_dnlink
invalid command name "atc::get_dnlink"
% load atc.so
couldn't load file "atc.so": atc.so: cannot open shared object file: No such file or directory
[andy@toaster|~/e6b]$ tclsh
% load atc.so
% atc::get_dnlink ABCD
conversion failed
% info patchlevel
8.6b2
% exec uname -a
Linux toaster 3.4.0-andy #2 Fri Jun 1 23:52:05 CDT 2012 i686 Pentium II (Deschutes) GenuineIntel GNU/Linux

Just so you know, that "conversion failed" message is the right result.

This library is not stubs-enabled. It also does not link against -ltcl8.6. Update: linking against -ltcl8.6 doesn't help; this error still happens.

I'd file a bug report, but the above is all the information I have at the moment. It seems like more is needed, yet I don't currently have any time to research further.

Update: here's another rather interesting failure mode:
[andy@toaster|~/e6b]$ tclsh
% load per.so
% per::get_integer ABCD 0 4
10
% load atc.so
couldn't load file "atc.so": atc.so: cannot open shared object file: No such file or directory
[andy@toaster|~/e6b]$ tclsh
% load atc.so
% load per.so
couldn't load file "per.so": per.so: cannot open shared object file: No such file or directory

Even when the first command doesn't result in an error, if the second or subsequent command is a [load], it fails. This makes it impossible to load more than one library.

The next step for me is to build the very latest Tcl and see if the problem persists.

Update 2: I just built the most recent trunk (1581f9beac5715890d105a41090756a89b0f3630 2012-06-15 09:39:34 UTC), but the problem persists, exactly the same as before. The system is running Slackware 13.1, if that helps. I might be able to fiddle around in gdb if anyone can point me toward something I ought to be looking at.

Update 3: This is only a problem for interactive use. Everything works fine when [load] is called from a script.

DKF: If you've omitted the return TCL_OK; at the end of the Init function (a bug in the code above that I just corrected), the result code will be a bit random (it'll depend on whatever happens to be in the relevant register!) and in your case that's causing this weirdness. No idea why that triggers in the precise failure mode you describe (I'd have to disassemble the init function to figure out, and possibly a few other things too!) nor do I care to dig further. Note that you should have been getting warnings about failing to return a value from a non-void function; those sorts of warnings are highly relevant, and indeed ought to always be errors…