Monday, August 16, 2010

C++ and OTcl Linkage: OTcl Commands — Binding OTcl and C++

Note: The content in this series is extracted from the book, Introduction to Network Simulator NS2. You may have to read chapter 3 of the book for better understanding.

Introduction
This post is the second post in the series on C++ and OTcl Linkage:

   1. Why Two Languages?
   2. Binding C++ and OTcl classes [Main steps, The mechanism].
   3. Variable binding
   4. OTcl command: Invoking C++ statements from the OTcl domain [ Getting Started, Invocation process, Binding OTcl and C++ ]
   5. Eval and result: Invoking OTcl statements from the C++ domain
   6. Object binding and object construction process.
In the previous post, I blogged about the key steps in the OTcl domain when instproc or OTcl command is invoked. In this post, I will explain how NS2 moves from OTcl to C++.

Let's Review Our Example
I will use the same example as in the last post. We will see the main steps when invoking

set obj [new MyOTclObject]
$obj show-delay

What We Discussed in the Last Post

In the last post, I took you through several key steps. And, the final step was to invoke instproc unknown of the SplitObject:

SplitObject instproc unknown args {
    if [catch "$self cmd $args" ret] {
        set cls [$self info class]
        global errorInfo
        set savedInfo $errorInfo
        error "error when calling class $cls: $args" $savedInfo
    }
    return $ret
}

This post will take it from this instproc.

cmd: The Glue to the C++ domain

Most of the content of the instproc unknown is to check for error. The only important statement is

$self cmd $args

The instproc cmd is bridges the OTcl domain to C++ domain. The above statement invokes the C++ function "command()" of the C++ class which is bound to OTcl class from which $self was instantiated.

From the above example, the statement will invoke the C++ function command(...) of C++ class MyObject, whose details are shown below:

1  int  MyObject::command(int argc, const char*const* argv)
2  {
3      if (argc==2) {
4          if (strcmp(argv[1], "show-delay") == 0) {
5              printf("Delay is %g\n", delay_);
6              return (TCL_OK);
7          }
8      }   
9      return TclObject::command(argc, argv);
10 };

Function command(argc,argv)

Function command takes 2 input arguments
  • argc is the number of input arguments
  • argv is an array of input arguments. It stores all the input parameters of the OTcl command, where argv[0] stores a string "cmd", argv[1] stores a string of the first input argument, and so on.
Example

The OTcl command invocation was

$obj show-delay

This statement is passed down to instproc unknown of class SplitObject, which in turn executes

$self cmd $args

where $self is $obj and $args is "show-delay". This statement is passed on to the C++ function command(argc,argv), where argc = 2, argv[0] = "cmd", and argv[1] = "show-delay".  Since argc and argv match both the "if" conditions (Lines 3 and 4), Line 5 is executed. And, a string "show-delay" is shown on the screen.

Return Value

As a final note, Line 9 is the default statement, which is executed if none of the above "if" conditions matches. Here it invokes the (same) function command of its base class (here class TclObject is the base class of class MyObject), and passes (argc,argv) as input arguments. The value returned from function command(...) of class TclObject will be returned to Line 9, and will be returned to the caller.
======================================================

T. Issaraiyakul and E. Hossain, “Introduction to Network Simulator NS2”, Springer 2009.
You may also find lecture notes and other resource at the following website: http://www.ece.ubc.ca/~teerawat/NS2.htm

No comments: