This is the README for TclExample.1.0.s.tar.gz [Download] [Browse] [Up]
TclObj - An Interface Between Objective-C and Tcl This package contains a simple class called TclObj whose purpose is to provide a salubrious interface between Objective-C and Tcl. Tcl is a small interactive C-Shell like language developed at UC Berkeley. You can obtain tcl from the UUNET archives. The main use of this class, as I see it, is to provide a programmable layer between a user interface built with Interface Builder and the 'guts' of an application. There are four components to this package: TclObj.{hm} - This is the implementation of the tcl interface class. TclApp.{hm} - This implements the tcl to application interface. TclTV.{hm} - This is a small text editor object for use in debugging tcl progs. TclIF.m - Procedure mappings between Tcl and 'C'. To hook tcl into a user interface with IB do the following: 1) An instance of TclObj should be created in the main .nib file for an application. 2) A segment called "TCL" with a section called "init" should be created in the program executable. The data in this segment/section should be the ascii text of the commands that you want to be executed when the TclObj is created. In the example I have a very simple set of start up commands that basically "source" in an external text file with the "real" start up stuff. If you wanted to have an application that doesn't have any external files hanging around you would put all your initializations into the "init" section. Note that TclObj initializes several useful global variables in the tcl interpreter that it creates. 'NXApp' is the ascii representation of the id for NXApp. 'TclObj' is the ascii rep for the TclObj instance id. These globals are initialized before the "init" section is evaluated. 5) Hook action messages from controls in the user interface to the 'msg' action in the TclObj. Each message that arrives will be converted to a tcl call to the procedure 'msg' with one argument which is the ascii representation of the senders id. At present this is the only interface from Objective-C into tcl. 7) If you want to invoke commands in the tcl interpreter from "outside" you can send the TclObj object a 'doCmd' message with the first argument being the string containing the tcl command and the second argument being NULL. At this point you should have a Tcl interface object linked into your user interface. The next problem is to control the user interface and the application from Tcl. In order to do this you need some way to call 'C' routines from Tcl. You could write a small Tcl to C converter routine for each C routine that you want to call but this would end up being a lot of procedures with much in common. In order to get around this I have implemented a routine called "tclCall". This routine takes a pointer to a 'C' procedure and a string containing a description of the procedure arguments (similar to the typed stream stuff). See the comments in TclApp.m for details on the use of tclCall. Part of the initialization of a TclObj is to define a bunch of procedures for the Tcl interpreter such that they call "tclCall" and pass along the required argument conversions. The list of definitions is defined in TclIF.m. In order to get Tcl access to more procedures from the NeXT library you would add lines to the list in TclIF.m. You would also add lines in this file to link in your application procedures. The interface from Tcl to Objective-C messages uses the above code. The Tcl "send" procedure is defined in TclIF.m to call "objc_msgSend". The argument description for this routine is an empty string which indicates that the actual argument string is passed in as the first argument to "send". This way you can form a wide variety of messages directly from Tcl without having to play with the low level C code. Debugging Tcl Procedures. I have provided a small class which implements a text editor / command input function for the TclObj class. You can create one or more tcl edit windows by invoking the 'createTextView:' message in the TclObj. If you have an edit window on the screen you may type tcl commands into it and execute them. The edit window acts like a standard NeXT text object except that I have intercepted the enter character to cause command invocation. The way this works is as follows. At the time you hit enter the code checks the current selection. If the selection is just an insertion point but has no width then the line that the insertion bar is on is evaluated by tcl and the results are added to the bottom of the edit text. If the selection has a width then the selection is evaluated by tcl and the result is added to the bottom of the edit window. The first edit window will display the result of commands invoked by the 'msg' message. Other edit windows will only echo results of commands typed into them. All edit windows share the same tcl interpreter. If you don't bring up an edit window then tcl output is ignored. In this case you could use the tcl 'print' command to write stuff on stdout if you invoked the application from a shell. Future Features. This code is a very machine dependent HACK but it does seem to work! Of course you could go a L...O...T further. You could get rid of the need to explicitly define the argument types for messages by using the new procedures provided for dealing with the "forward" and "performv" methods. You could allow dynamic addition of methods to the TclObj class. You could use symbol table information to dynamically call C routines. All of this comes under the heading of a "correct and complete" interface between Tcl and C/Objective-C. If you get time to add any of these (or any other) features I would be interested in having a look. WARNING STUDENT DRIVER. I wrote this class as my first NeXT project so beware! Enjoy, Grant Munsey, Manticore, Inc, grant@gouche.portal.com, (408)733-3838
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.