|
|
|
Home Sponsors Download Install Running Examples Tcl Scripts News Future Work Copyright |
Setting up your Tcl Interpreter to use CABLE-generated WrappersGenerated Tcl wrapper libraries do not run by themselves. They require a Tcl package called "cable" which is provided by CABLE. This package not
only provides some convenient commands, but is also in charge of
coordinating the interaction of multiple wrapper packages. All
CABLE-generated wrapper packages tell the interpreter that they
require the cable package when they load.
Generated Tcl wrapper packages link to the
"
DO NOT attempt to use both an installed CABLE and a copy
from the build directory. The Using the CABLE-generated WrappersIn order to write Tcl scripts that use wrapped C++ classes, you will have to be familiar with the syntax of creating objects and invoking methods from Tcl. Most of the language semantics are close approximations to the behavior in C++. This includes automatic object destruction, overload resolution, and reference and pointer semantics. For the reference by the examples included in the instructions below, consider this simple C++ class:
class Integer
{
public:
Integer(): m_Int(0) {}
Integer(const Integer& r): m_Int(r.m_Int) {}
Integer(int i): m_Int(i) {}
~Integer() {}
int Get() const { return m_Int; }
void Set(int i) { m_Int = i; }
const Integer* GetPointer() const { return this; }
Integer& operator+=(const Integer& r)
{ m_Int += r.m_Int; return *this; }
static float Mean(const Integer& l, const Integer& r)
{ return (float(l.m_Int)+float(r.m_Int))/2.0; }
private:
int m_Int;
};
ConstructorsUnlike other object-oriented systems in Tcl, instances of wrapped classes do not have names. Instead, they are associated with Tcl objects, which can be referenced by Tcl variables, lists, arrays, and other data structures. Any wrapped class that has public constructors available provides a Tcl command with the name of the class. Invoking this command will create an instance of the class by calling a constructor selected by C++ overload resolution:
class-name arg1 arg2 ...
The command will return an instance of the class as the Tcl result.
You can store a reference to this object in a Tcl variable using
the "set" command. For example, we can create instances
of the Integer class like this:
# Create an Integer object with value 0.
set x1 [Integer]
# Create an Integer object copied from $x1.
set x2 [Integer $x1]
# Create an Integer object with value 578.
set x3 [Integer 578]
An important note is that Tcl variables act as references to the
objects. After creating the above objects, the command
"set x2b $x2" will NOT create a copy of the
Integer object. It simply adds another Tcl reference to it.
To create a copy, you must explicitly call the copy constructor,
as in the example above to copy $x1.
DestructorsWhen Tcl loses all references to an object, its destructor is automatically called:
# Delete an Integer object created in the example above.
set x3 {}
# The Integer with value 578 has been destroyed.
This will also work for local variables in Tcl procedures:
proc Foo {} {
# Create an Integer object.
set temp [Integer 5]
return 0
# The Tcl variable "temp" goes out of scope,
# so the Integer object is destroyed.
}
MethodsOnce you have an instance of a class, you can invoke methods on it by using the object itself as a command. The first argument to the command is the name of the method you want to invoke. Additional arguments will be passed to the method when it is called, and are used in overload resolution:
object method-name arg1 arg2 ...
The result of the command will be the value returned by the method.
This value can be stored in a Tcl variable, ignored, or passed
directly into another method invocation.
As an example, we can invoke some methods on the Integer objects
created in the above example:
# Set the first Integer to value 6.
$x1 Set 6
# Print out the value of the second integer.
puts [$x2 Get]
# Set the value of the second integer to that of the first.
$x2 Set [$x1 Get]
Some methods may return C++ pointers or references to objects. If
the classes of these objects have been wrapped, you can call methods
directly through the pointer or reference, with no special syntax.
For example, if we call GetPointer on an Integer object,
we will get a pointer of type "const Integer*". We can save this
pointer and use it to invoke methods. However, const correctness is
enforced, so in this example, we will only be able to invoke const
methods:
# Get a pointer to the Integer referenced by x1.
set p1 [$x1 GetPointer]
# Call the "Get" method, which is const.
puts [$p1 Get]
# Try to call the "Set" method. This should
# produce an error.
$p1 Set 3
Static MethodsJust as in C++, static methods can be invoked with or without an instance of the class. Invoking the methods with an instance works just like any other method:
object static-method-name arg1 arg2 ...
Static methods can also be invoked through just the name of the class:
class-name static-method-name arg1 arg2 ...
For example, we can call the "Mean" method to find the average value of
two Integer objects created above:
set mean [Integer Mean $x1 $x2]
puts "The mean value is $mean"
OperatorsAny operator that is defined as a member of a class can be invoked by its name using the same syntax as calling a method. For example, we can add one Integer object to another like this:
$x1 += $x2
puts "Sum = [$x1 Get]"
Namespace-level Functions and OperatorsFunctions and operators not defined in a class scope are currently NOT supported. There are no known technical difficulties with adding the support, but grouping the functions and operators into packages requires more complicated configuration files. This functionality has not yet been implemented.Commands Provided by the
The |