翻译自NS by Example,见笑
![]() 图18
1.将C++类导出至OTcl 假定你已经使用C++创建了一个新的网络对象类,比如继承自Agent类的MyAgent,并且你想在OTcl中创建该对象的实例。为此,你必须定义一个继承自TclClass的连接对象,比如MyAgentClass。该连接对象用于创建一个有着特定名称(如该例的Agent/MyAgentOtcl)的OTcl对象,并且在OTcl对象和C++对象(如该例中的MyAgent)之间创建连接。并且在C++对象的create成员函数中指定了实例的开始过程(launching procedure)。 2.将C++变量导出至OTcl 假设你的新的C++对象MyAgent中有两个参数变量,比如my_var1和my_var2,这两个变量必须够够通过使用OTcl模拟脚本来很容易地进行配置(或改变)。为此,你应当对C++类中的每个你想导出的变量使用绑定函数。绑定函数在对应的OTcl对象类(如Agent/MyAgentOtcl)中使用给定的名字(第一个参数)创建新的成员变量,并且建立在OTcl变量和C++变量(变量的地址通过第二个参数确定)之间的双向绑定。图19显示了怎样对图18中的两个变量my_var1和my_var2进行绑定。 ![]() 图19
注意,为了在对象的实例被创建时建立绑定,绑定函数应放置在MyAgent的构造函数内。NS支持4种不同的绑定函数,适用于如下5种不同的变量类型:
- bind(): 浮点型和整型变量 - bind_time(): 时间变量 - bind_bw(): 带宽变量 - bind_bool(): 布尔变量 通过这种方法,使用OTcl脚本来设计并进行模拟的用户可以对使用C++实现的网络组件中的可以配置的参数(或者变量值)进行访问或者改变。注意,强烈建议无论何时导出一个C++变量,都应当同时在ns-2/tcl/lib/ns-lib.tcl中设置该变量的默认值。否则,当创建新对象的实例时会有警告信息。 3 .将C++对象控制命令导出至OTcl
图20. 一个OTcl命令解释器除了要导出你的C++对象的一些变量之外,你可能还想让OTcl得到你的C++对象的控制权。这可以通过定义你的C++对象(例如,MyAgent)的command成员函数来实现。该成员函数充当OTcl命令的解释器的角色。事实上,在C++对象的command成员函数中定义的OTcl命令看起来与相应的展示给用户的OTcl对象的成员函数相同。图20是一个一个对图18中的MyAgent对象的command成员函数的定义例子。 ![]() 图20
当匹配MyAgent对象的OTcl影像对象的实例在OTcl内被创建(例如,使用了set myagent [new Agent/MyAgentOtcl]命令),并且用户试图调用该对象的成员函数时(例如,使用$myagent call-my-priv-func),OTcl会在OTcl对象中搜索给定的成员函数名。如果给定的成员函数名未能找到,那么将会调用MyAgent::command来以“参数名/参数值”的形式传递被调用的OTcl成员函数的参数的名称和参数值。如果在command成员函数中存以在被调用的OTcl成员函数的名称定义的操作,那它执行请求并返回结果。如果不存在,command成员函数的祖先会被依次递归调用,直到发现该名称。如果在任何一个祖先中都未能发现该名称,则返回给OTcl对象一个错误信息,并且该OTcl对象显示给用户一条错误信息。通过这种方式,用户可以在OTcl内控制C++对象的行为。
4.从C++中执行OTcl命令
如果你用C++实现了一个新的网络对象,你或许从C++对象中执行一条OTcl命令。图21显示了图18中的MyAgent对象的MyPrivFunc成员函数的实现。它让OTcl解释器打印出私有成员变量my_var1和my_var2的值。 为了从C++中执行一条OTcl命令,你应当取得到Tcl::instance()的引用(reference),该引用被声明为一个成员变量。它给你提供了若干函数,使用这些函数,你可以给解释器传递OTcl命令(MyPrivFunc的第一行)。该例展示了想解释器传递OTcl命令的两种方法。要取得OTcl命令传递函数的完整列表,请参考NS手册。 ![]() 图21
5.编译,运行和测试
至今为止,我们使用MyAgent例子检测了NS中基本的OTcl连接的可用性。假设运行并且测试该例子可以帮助读者理解得更加深刻。我们给了一个可以帮助你编译、运行、测试MyAgent的步骤。 1. 下载ex-linkage.cc文件,并将其保存在NS2目录下
2. 打开Makefile,将ex-linkage.o添加至目标文件列表中 3. 使用make命令重新编译NS 4. 下载ex-linkage.tcl,该文件包含了测试MyAgent的OTcl命令。(图22显示了输入的脚本和相应的结果) 5. 使用ns ex-linkage.tcl命令运行OTcl脚本 ![]() 图22 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhaomingliang/archive/2007/03/16/1531712.aspx
该类写好后,将.h文件(如果有的话,一般都会有)和.cc文件放置于 ns-allinone-2.28/ns-2.28/目录下自己新建的一个子目录(假如叫bear)中,然后打开 ns-allinone-2.28/ns-2.28/Makefile文件,将 bear/ex-linkage.o 添加到该Makefile的OBJ_CC宏定义中,以便在对ns进行编译的时候能够找到该模块的源文件并将其编译到ns中;此外,打开 ns-allinone-2.28/ns-2.28/tcl/lib/ns-default.tcl文件,为该类对应的Otcl类设置一些初始值。最后,利用Makefile,对整个ns重新编译,就可以是使用新添加的模块了。
//myagent.cc #include
|
|