00001 /** \dir src/tcl 00002 00003 \brief core components for exposing c++ objects/functions to a tcl script interpreter 00004 00005 src/tcl offers a framework with which to easily create tcl wrappers 00006 around c++ code. In a tcl script application (see tcl::script_app), 00007 the program loads a series of "packages", each with its own 00008 initialization function, and then starts reading and evaluating 00009 commands from stdin. The package-initialization functions define 00010 the commands that will be understood by the script interpreter. 00011 00012 According to the Tcl C API, these init functions must have names 00013 like Packagename_Init(). In this c++ framework, Tcl::Pkg offers a 00014 way to quickly set up such an init function. As an example, see the 00015 definition of Dlist_Init() at the end of tcl/tclpkg-dlist.cc. Here, 00016 the macro GVX_PKG_CREATE() is used to create a Tcl::Pkg (and the 00017 macro additionally transparently creates a try/catch context, so 00018 that exceptions can be translated into error codes to be returned 00019 from the init function). Then there are a series of pkg->def() 00020 calls that bind various c++ functions to tcl commands. 00021 00022 For most c++ functions, this binding happens seamlessly -- as long 00023 as there are appropriate c++/tcl conversions defined for the types 00024 of the function parameters and for the function's return type. The 00025 converters for basic built-in types are defined in 00026 tcl/conversions.h, and additional converters can be defined by the 00027 user (see tcl/stdconversions.h for an example of extra converters 00028 for std::string). 00029 00030 Finally, src/tcl offers some c++-friendly wrappers for native tcl 00031 components. For example, tcl::list offers an interface to tcl list 00032 values, complete with c++-style iterators, and with templatized 00033 type conversions (e.g., so that you can say "give me the third 00034 value from the list, as a 'double'"). There is also 00035 tcl::interpreter, tcl::obj, tcl::dict, and tcl::regexp. 00036 00037 For more insight into the internals of what happens with 00038 tcl::pkg::def(), see tcl::command, tcl::commandgroup, 00039 tcl::dispatcher, and tcl::context. Basicaly, tcl::pkg::def() 00040 creates a tcl::function object using the highly templatized 00041 functions in tcl/makecmd.h. This tcl::function knows how to accept 00042 a tcl::calll_context, translate the tcl argument types into their 00043 c++ counterparts, then calls the native c++ function, then 00044 translates the c++ return value back into a tcl result. The 00045 tcl::function is used to create a tcl::command object becomes part 00046 of a tcl::commandgroup which can potentially select among 00047 overloaded tcl::command objects based on the number of arguments in 00048 a given tcl command invocation. 00049 00050 Here is the dynamic view: it is tcl::commandgroup that is 00051 responsible for actually registering a command with Tcl's low-level 00052 C API. When a callback comes from that API saying that the user has 00053 entered a command, control is first passed to 00054 tcl::command_group::invoke_raw(), where we first try to find a 00055 matching tcl::command overload, and then send control to 00056 tcl::command::call(). There we forward control to the 00057 tcl::dispatcher::dispatch(). In the standard case, this function 00058 will create a tcl::call_context from the array of Tcl_Obj*'s that 00059 we got from the low-level C API, and then call 00060 tcl::function::invoke() with this tcl::call_context. Remember that 00061 some templatized subclass of tcl::function is wrapping our native 00062 c++ function. If our c++ function throws an exception, it will be 00063 caught back in tcl::commandgroup::invoke_raw() and translated into 00064 an error code and error message to the tcl interpreter. If our c++ 00065 function completes successfully, then its result will be returned 00066 to the tcl interpreter via tcl::call_context::set_result(). 00067 00068 */ 00069 00070 /////////////////////////////////////////////////////////////////////// 00071 // 00072 // Copyright (c) 1998-2005 00073 // Rob Peters <rjpeters at usc dot edu> 00074 // 00075 // created: Wed Jul 6 14:23:50 PDT 2005 00076 // commit: $Id: README.dxy 11876 2009-10-22 15:53:06Z icore $ 00077 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/tcl/README.dxy $ 00078 // 00079 // -------------------------------------------------------------------- 00080 // 00081 // This file is part of GroovX 00082 // [http://ilab.usc.edu/rjpeters/groovx/] 00083 // 00084 // GroovX is free software; you can redistribute it and/or modify it 00085 // under the terms of the GNU General Public License as published by 00086 // the Free Software Foundation; either version 2 of the License, or 00087 // (at your option) any later version. 00088 // 00089 // GroovX is distributed in the hope that it will be useful, but 00090 // WITHOUT ANY WARRANTY; without even the implied warranty of 00091 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00092 // General Public License for more details. 00093 // 00094 // You should have received a copy of the GNU General Public License 00095 // along with GroovX; if not, write to the Free Software Foundation, 00096 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00097 // 00098 ///////////////////////////////////////////////////////////////////////