1

I want to have my C++ application to enable package autoloading for all ActiveTcl packages in C:\Tcl\lib. I pass below tcl command to Tcl_Eval() in my C++ code. And expect "package require <package name>" will automatically find the package and load it.

set ::auto_path [file join {C:\Tcl\lib}]

But it didn't work as what it does in TCL shell - TCL shell looks for pkgIndex.tcl in auto_path, so when "package require", it can find the right package or shared libs. Is it possible to make it work in C++ application? Or is there any better way?

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
Stan
  • 37,207
  • 50
  • 124
  • 185
  • 1
    Did you initialize the Tcl interpreter correctly? Especially a call to `Tcl_FindExecutable()` http://www.tcl.tk/man/tcl8.5/TclLib/FindExec.htm – schlenk Aug 30 '12 at 18:45
  • I did. Checking "info nameofexecutable" returns the right information. – Stan Aug 31 '12 at 08:29
  • By the way, $::auto_path is undefined in the Tcl interpreter in my application. Is that normal? – Stan Aug 31 '12 at 09:03
  • 1
    Usually it is defined when init.tcl is processed, so you seem to lack the script library initialization. Have a look at this thread, especially the answer by Don Porter: https://groups.google.com/forum/?fromgroups=#!topic/comp.lang.tcl/KdPdMzur5T4 – schlenk Aug 31 '12 at 10:25
  • It's working now. By setting $tcl_library and call Tcl_Init to load init.tcl. Thanks @schlenk. – Stan Aug 31 '12 at 16:47

1 Answers1

0

OK, I think I know what the problem might be. The auto_path is a Tcl list of directories — the code that uses it iterates over the list with foreach — that are searched for packages (and auto-loaded scripts, an old mechanism that I think is rather more trouble than it's worth). Yet you're using a single element, the output of that file join. This wouldn't usually matter on platforms other than Windows, as the directory separator is / there (and that's just an ordinary non-whitespace character to Tcl) but on Windows the directory separator is \ and that's a list metasyntax character to Tcl.

What does this mean? Well, after:

set ::auto_path [file join {C:\Tcl\lib}]

We can ask what the things of that list are. For example, we can print the first element of the list…

puts [lindex $::auto_path 0]

What does that output? Probably this:

C:Tcllib

OOooops! The backslashes have been taken as quoting characters, leaving an entirely non-functioning path. That won't work.

The fix is to use a different way to construct the auto_path. I think you'll find that this does what you actually want:

set ::auto_path [list {C:\Tcl\lib}]

Though this is an alternative (still using list; it's best for trouble-free list construction in all cases):

set ::auto_path [list [file normalize {C:\Tcl\lib}]]

(My bet is that you're trying to use file join as a ghetto file normalize. Don't do that. It's been poor practice for a long time now, especially now that we have a command that actually does do what you want.)

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215