I have an application which support plugins.
These plugins can be reloaded at any time
and their state is preserved in the "core" application.
This allows me to actively develop a plugin
and to test the results of any changes and compare
it to the previous version, without restarting
the main application.
So now I'm beginning to push the core application
beyond it's original intent,
and I figure the best way to do this is to give
it the power and scriptability that Tcl provides.
Ideally, I'd like to make each plugin a Tcl Package,
and then be able to ask for the core application
to reload a package if I modify it.
Looking at the "load" command doc, it looks like
unloading is impossible. Is anyone aware of an alternative
method that I can use to get this effect?
The way I do it in C is to have all the plugins dynamically
loadable shared libraries, which register themselves and the
commands they provide (a la Tcl Packages I guess.) But in C,
I can just close the library, deregister the commands, and reopen
the new one.
Any help, comments, and suggestions would be greatly appreciated!
Thanks,
Sam.
George
"sbromle" <s...@sambromley.com> wrote in message
news:1141747942....@i40g2000cwc.googlegroups.com...
I've downloaded the Tcl8.5 source in a hope to see how the
unloading facility is implemented, but it looks more invasive
that I anticipated. (Probably because I am not very familiar
with the organizational structure of the Tcl code base.)
I have an idea on how I could quickly emulate the effect, but
I'm not sure if this would work, so I would appreciate your input.
If I manually dynamically load the shared libraries on the C side
(thus I handle the "load" myself), and then, upon "unload", I :
1) rename all the registered commands to the empty string
2) save the state of the plugin (if any)
3) unload it (basically just close the library)
4) then reload it
5) register the commands, and
6) restore the state,
will the state of the main interpreter be ok?
I guess the question is, does the registering of a comand, followed by
the
renaming of that command to the empty string, return the interpretor to
the
same state as before the initial load?
Thanks!
Sam.
if it would be a pure tcl package I would say, use ...
% package forget abc
% package require abc
1.0
But if it's about C(++) related shared libraries loaded into tcl, than
you must use tcl 8.5 to use the unload command.
The unload command asks for an unload function to execute this function
like the load command asks for an init function while loading the
shared library.
Due to the problem, that packages (loaded by "package require") have no
"forget" or "unload" callback, a package should provide a "unload"
procedure or command to unload itself.
After unloading it can be reloaded, hopefully!
But be careful while unloading to reload to clean up everything, that
may influence the reload in a non-wanted way!
Best regards,
Martin Lemburg
UGS - Tranforming the Process of Innovation
Thanks for the help.
Sam.
If you can't/don't want to use the 8.5 'unload', I'd have the
init-code of the shared library create an TCL-unload-proc for that
library. Something in the line of
static int unload_foo(Clientdata interp...) {
// in interp:
// rename all commands to {}
// delete all variables created {}
// free all memory etc
// dlclose? dunno...
//
}
int Foo_Init(Tcl_Interp interp) {
...
Tcl_CreateObjCmd(cmd1,...);
...
Tcl_CreateObjCmd(unload-FOO, ..., (Clientdata) interp, unload_foo);
return TCL_OK;
}
Then if you 'load' the lib, Foo_Init() is called which creates the
unload proc. Later, you call the unload-proc, either from TCL or from
C et voila...
Haven't tried that myself...
R'
If anyone happens to think up any "watch out for"'s, please don't
hesitate to shout out. :)
Thanks for the input.
Best regards,
Sam.
George
"sbromle" <s...@sambromley.com> wrote in message
news:1141750601.4...@p10g2000cwp.googlegroups.com...
You want to use Tcl_DecrRefCount() for this, methinks.
- Adrian
No, that's a completely different topic.
Once you register a Tcl_ObjType with Tcl_RegisterObjType(), you're
stuck. You won't be able to [unload] that extension.
The solution? Don't call Tcl_RegisterObjType().
There's no need to register your Tcl_ObjType in order to use it to
your heart's content within your extension, and the Tcl_ObjType need
not be registered in order to pass through the core.
It turns out that there are very few situations where registering the
Tcl_ObjType with the core has any value. Just don't do it, at least
not until experience has convinced you there's something you just can't
accomplish without doing so.
--
| Don Porter Mathematical and Computational Sciences Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|
Argh, you're right.
Note to self: Rub sleep from eyes + get caffeine jolt before posting...
- Adrian
The [package forget] command does NOT unload a pure Tcl package, it
simply instructs the interpreter to forget about previously found
[package ifneeded] scripts for that package.
See The Simple Development Library
http://simpledevlib.sourceforge.net/
and, more specifically, the SimplePackage package
http://simpledevlib.sourceforge.net/SimplePackage.html
for more no this issue.
Juan Carlos---