1. 程式人生 > >NS2入門學習(五)之分裂物件模型和TclCL

NS2入門學習(五)之分裂物件模型和TclCL

 TclCL其實就是連線C++與Otcl,實現兩者的互相操作和兩者之間類的對應.

NS中使用兩種語言原因:

C++執行速度較快,是強制型別語言(進行嚴格的資料型別檢查),容易實現複雜的資料型別和精確/複雜的演算法。但是修改/debug和重新編譯時間較長,所以適合完成網路協議等各種模擬環境的演算法的實現。

Otcl執行速度慢,但是可以很方便的修改,不需要編譯,而且不是強制型別的,適合用來做模擬的環境的配置。

以下情況使用Otcl:

對模擬場景的建立、配置、和模擬中只需要執行依次的程式;另一種時如果通過Otcl指令碼操作已經存在的C++物件就能很方便的達到目的。

以下情況使用C++:

需要對一個數據流的每個分組進行處理的任何工作;如果你必須修改已存在的C++類的行為。

1、分裂物件模型之C++與Otcl對應關係和命名規則


NS 的構件都是由相互關聯的兩個類來實現,一個在C++中,一個在Otcl中,因此包含了如上圖的一個C++類的層次結構和一個Otcl類的層次結構。主要功能通常在C++程式中實現,Otcl類則主要提供C++物件面向使用者的配置介面。 每當例項化一個構件時,都會同時建立一個Otcl中的物件和一個對應的C++物件,並且兩個物件可以互操作。如下圖
類的命名規則:在分裂物件模型中,所有的c++類都是從TclObject一級級繼承出來。所有的Otcl類都是從SplitObject一級級繼承出來的。A/B/C/D是A/B/C的子類。“/”表示一級級的繼承關係。

2、分裂物件模型之C++與Otcl之間的物件連線

TclObject和TclClass   

TclCL是通過TclObject和TclClass兩個C++類,把Otcl類和C++類關聯起來的。TclObject是所有編譯類的基類,對應的SplitObject是所有解釋類的基類。 建立和銷燬TclObject:
在Otcl指令碼中使用過程new{}和delete{},例如 set tcp1 {new Agent/TCP} delete $tcpl 過程new{}首先創建出解釋物件,然後會執行該物件的初始化例項過程init{},並把使用者提供的引數傳給它。在基類SplitObject的初始化例項過程中會通過 create-shadow方法建立物件在C++中的影像物件,此時該影像物件的建構函式將會被執行,其中通常會進行一些變數繫結工作。因此每個解釋類都必須在初始化例項的過程中呼叫父類的初始化例項過程,以便最終能夠執行到SplitObject的初始化例項的過程去建立影像物件。建立影像物件時將進行變數繫結,最好呼叫父類的初始化例項過程要先於當前類的初始化,以便繫結變數能夠儘早被建立。 如果使用者直接在C++中建立一個編譯的TclObject,Otcl中的影像物件時不會被建立的。 因此在NS中禁止直接使用C++的new操作來建立編譯物件。最終,在基類splitObject的銷燬過程中將呼叫例項過程 delete-shadow,這將導致影像物件被析構。 create-shadow方法建立的影像物件屬於C++中的哪個類,是由TclClass來確定的。TclClass是個純虛類,從這個基類繼承出來的類提供兩個功能:1,構造與編譯類對應的解釋類結構 2,提供初始化新的TclObject的方法。每個從TclClass繼承出來的類都和編譯類結構中的一個TclObject的子類相關聯,並能初始化所關聯類的新的物件。
static class RenoTcpClass:public TclClass {
public:
        RenoTcpClass():TclClass("Agent/TCP/Reno"){}
        TclObject* create(int argc,const char*const *argv  )
         {return(new RenoTcpAgent());}
}class_reno;}
上面之定義了一個方法create,用以建立所關聯的TclObject子類的例項。而在其建構函式中通過呼叫基類的建構函式TclClass("Agent/TCP/Reno")指定了其對應的解釋類為Agent/TCP/Reno。這實際上是做了一種登記工作,以後每當在直譯器中建立Agent/TCP/Reno時,create-shadow都會來呼叫這個RenoTcpClass的create函式,這樣就創建出正確的影像物件,其實也起到了生命Otcl類的作用。 變數繫結: NS 中解釋物件的成員變數和編譯物件的成員變數都訪問相同的資料,且當任何一邊的變數值改變時對應另一邊的變數也改變為相同的值。繫結通常是在當該物件初始化時在編譯物件的建構函式中建立的。 command()方法
要在Otcl物件中呼叫對應的C++物件的方法,NS是通過command()函式實現的,對於每一個TclObject,ns為其Otcl中的解釋物件建立一個例項過程,cmd{}。過程cmd{}呼叫影像物件的方法command(),並將cmd{}的引數作為一個引數陣列傳遞給command()方法。使用者呼叫cmd{};可以通過顯示的呼叫,即將進行的操作指定為第一個引數;或者可以隱式的呼叫,就像是存在一個和欲進行的操作同名的例項過程一樣。