接下来要进入对我来说老大难的环节了,从表面的TCL慢慢进入到后端的C++,一起加油学习吧~
在本节学习中,将给出一个在ns中实现新的协议的例子。但是可以想见的是,如果由我们自己来完成这个工作,势必要对NS2十分的熟悉并且要对c++的相关知识有一定了解(课程中有这门课,表示hold不住,学精一门语言是多么重要)。在开始这项工作以前,读者应该先至少要了解TCL与c++之间的联系。可以从 学http://www.isi.edu/nsnam/ns/tutorial/ 的3.1-3.3开始。
下面首先来列举一下3.1-3.3到底说了什么东西。
3.1 Concept Overview
为什么选择两种语言? ns使用两种语言,因为模拟器有两种不同的事情需要做。 一方面,协议的详细模拟需要一种系统编程语言,可以有效地操纵字节,数据包头和实现在大数据集上运行的算法。 对于这些任务,运行时速度很重要,周转时间(运行模拟,查找错误,修复错误,重新编译,重新运行)不太重要。——选择了C++
另一方面,网络研究的很大一部分涉及到稍微变化的参数或配置,或者很快地探索了一些场景。 在这些情况下,迭代时间(更改模型并重新运行)更为重要。 由于配置运行一次(在模拟开始时),这部分任务的运行时间不太重要。——选择了TCL
什么时候使用C++呢?① 在做任何需要处理流的每个数据包的东西;② 以未预期的方式更改现有C ++类的行为;
什么时候使用TCL呢? ① 用于配置,设置和“一次性”的东西;② 通过操作现有的C ++对象来执行所需的操作;
3.2 代码概述
在〜tclcl /中定义了一些类。我们只专注于ns中使用的六个:
① TclSectionsec类:Tcl包含C ++代码将用于访问解释器的方法。
② TclObjectSectionsec类:TclObject是在编译层次结构中也被镜像的所有模拟器对象的基类。
③ TclClassSectionsec类:TclClass定义了解释类层次结构以及允许用户实例化TclObject的方法。
④ TclCommandSectionsec类:TclCommand用于定义简单的全局解释器命令。
⑤ EmbeddedTclSectionsec类:EmbeddedTcl类包含加载更高级别内置命令的方法,使配置模拟更容易。
⑥ InstVarSectionsec类:InstVar类包含访问C ++成员变量作为OTcl实例变量的方法。
3.3 TCL类
Tcl ../Tcl / Tcl.h封装了OTcl解释器的实际实例,并提供了访问和与该解释器通信的方法。 该类提供了以下操作的方法:
① 获取对Tcl实例的引用;
② 通过解释器调用OTcl程序;
③ 将结果回收给解释器;
④ 报告错误情况,统一退出;
⑤ 存储和查找“TclObjects”;
⑥ 得到直接访问解释器的方法;
在下面6个小节中仔细分析这六个方面;
①
该类的单个实例在〜tclcl / Tcl.cc中声明为静态成员变量; 程序员必须获得对该实例的引用以访问本节中描述的其他方法。 访问此实例所需的语句是:
Tcl&tcl = Tcl :: instance();
②调用OTcl程序
通过实例tcl调用OTcl命令有四种不同的方法。他们 的调用方式有本质上的不同。 每个函数将一个字符串传递给解释器,然后在全局上下文中对该字符串求值。 如果解释器返回TCL_OK,这些方法将返回给调用者。 另一方面,如果解释器返回TCL_ERROR,则方法将调用tkerror。 用户可以重载此过程,以选择性地忽略某些类型的错误。 OTcl编程的复杂性超出了本文档的范围。
③ 返回值
当解释器调用C ++方法时,它会将结果返回到私有成员变量tcl_-result中。 有两种方法可用于设置此变量。
[const char* $s$]tcl.result../Tcl/Tcl.hTcl::result
将结果字符串$ s $传回给解释器。
[const char* fmt, ...]tcl.resultf../Tcl/Tcl2.ccTcl::resultf
varargs(3)以上变体使用vsprintf(3)格式化结果,将结果字符串传回给解释器。(翻译无能。。。。)
同样,当C ++方法调用OTcl命令时,解释器将返回tcl_-result中的结果。
tcl.result ../ Tcl / Tcl.hTcl :: result必须用于检索结果。 请注意,结果是一个字符串,必须转换成适合于结果类型的内部格式。
tcl.evalc("Simulator set NumberInterfaces_");char* ni = {\bfseries{}tcl.result}();if (atoi(ni) != 1)tcl.evalc("Simulator set NumberInterfaces_ 1");