Saturday, June 12, 2010

C++ and OTcl Linkage: Binding C++ and OTcl classes -- Part I

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
   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 motivation of having 2 languages. In this post, I will show you how to bind a C++ class to an OTcl class so that when an OTcl object is created, a shadowed C++ object is automatically crated.
Explanation by Examples

Here is what I would do in this post:

Suppose I have a C++ class "MyObject" and an OTcl class "MyOTclObject".
I would like to bind these two classes together so that when I call

new MyOTclObject

from the OTcl domain, a shadow C++ object is automatically created.

Key Steps

I. Create a C++ class "MyObject".
II. Bind two class names "MyObject" and "MyOTclObject" together.
III. Incorporate the classes into NS2 using the Make utility.
IV. Test.

Note that all these steps are done in 2 files: otcl.h and otcl.cc

Step I: Create a C++ class "MyObject".

You can do so by defining the new class in the file otcl.h

#include "object.h"
class MyObject : public TclObject {
public:
  MyObject();
  virtual ~MyObject(){};
};

Step II:  Bind two class names "MyObject" and "MyOTclObject" together.

Here is the detail in the file otcl.cc.

#include "otcl.h"
static class MyObjectClass : public TclClass {
public:
    MyObjectClass() : TclClass("MyOTclObject") {}
    TclObject* create(int, const char*const*) {
        return (new MyObject());
    }
}  class_my_object;
I will explain the details in the next post.

Step III. Incorporate the classes into NS2 using the Make utility

Make change to the file ~ns/Makefile. Look for the following section beginning with 

OBJ_CC = \
    tools/random.o \
    ...

Then add the following line to the end of this section

<YOUR_DIR>/ otcl.o

Do not forget to put '\' between two lines.

Then at command prompt, run

>> make

The new classes MyObject and MyOTclObject should be incorporated into NS2.

Step IV. Test

One last thing that we should do is to test whether what we did works. So just run NS2, and you should see the following results.

>> ns
% new MyOTclObject
_o4
%

which means an OTcl object _o4 was created.
Summary
So if you would like to bind C++ and OTcl classes, you can just copy the following code and put the class name in the relevant place.

static class <ANY CLASS NAME> : public TclClass {
public:
    MyObjectClass() : TclClass("<YOUR OTCL CLASSNAME>") {}
    TclObject* create(int, const char*const*) {
        return (new <YOUR c++ CLASSNAME>());
    }
} <ANY OBJ NAME>;

Wrap-Up

That's it! It is not that hard to bind a C++ class to an OTcl class, right? In fact, this process is used repeatedly in NS2. Look for example at

- C++ class DropTail, which is bound to OTcl class Queue/DropTail in file ~ns/queue/droptail.cc
- C++ class Connector, which is bound to OTcl class Connector in file ~ns/common/connector.cc
- C++ class TcpAgent, which is bound to OTcl class Agent/TCP in file ~ns/tcp/tcp.cc

Although the key step are quite straightforward, the process is interesting. I will blog about the process later in the next post. Stay tune!
=======================================================
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: