Veins教程05 - 再学OMNet++
Learn more about OMNet++
对Veins有了一些基础的了解之后,在修改/搭建自己项目之前,回头再深入学习一些Omnet++的知识
Messages
OMNet++中Messages的相关知识。Message的对应.cc
类文件为omnetpp/include/omnetpp/cmessage.cc
。cMessage类的构造函数包括name和kind,前者可以用于标识、debug等,后者接受一个非零数(通常为定义的枚举类型),负数预留给仿真内核使用。
cMessage * msg3 =newcMessage("timeout", KIND_TIMEOUT);
属性基本都是字面意思,特殊的是timestamp
,这个是可以自由定义,做任何用处的属性。
函数dup()
克隆Message,除ID以外完全一致。克隆的Message与原Message的TreeID一致。
函数getCreationTime()
返回的是创建时间。需要注意的是,通过克隆的Message使用此函数返回的是原Message的创建时间而非克隆时间。
函数setControlInfo()
可以附一个控制体给Message,以此来包含特殊信息。比如IP消息中包含接收方的MAC地址。
setControlInfo() 意义不明
Message内有一个cArray储存cObject,可以用于附加各种参数或对象到Message。
1 | // sender: |
Message Definitions
OMNet++提供一个方便的方法定义Message。我们可以创建.msg
文件,编译器会帮我们创建对应的.h
和.cc
文件。比如veins/src/modules/messages
中*_m.h
和*_m.cc
文件为编译器根据对应的.msg
文件创建的。
如果定义中使用的类型包含在其他特定c++文件中,需要引用。例如veins/src/modules/messages/BaseFrame1609_4.msg
中使用了SimpleAddress.h
中定义的LAddress
类:
1 | cplusplus {{ |
cplusplus
内可以直接使用C++的引用和预定义代码。需要注意的是,引用了头文件后,还需要手动定义该类,如上例的class LAddress::L2Type extends void;
所示,其空继承等于class noncobject LAddress::L2Type
。如果没有写明extends
则会自动继承cOwnedObject
以确保错误在编译时出现而不是留到运行时。
Customized Message
编译器自动生成的c文件可能无法很好的实现我们所需的功能,直接修改生成的c文件无效,因为编译器会根据.msg
文件重新生成覆盖。我们可以添加@customize(true)
来自定义功能。具体的逻辑是:编译器会自动生成*_Base
类,然后我们手动编写c文件并继承_Base
类,然后实现功能。
Using STL
两种方式在Message中使用类似std::vector
和std::stack
的标准库:
在
.msg
中引入并声明类型1
2
3
4
5
6
7
8
9
10cplusplus{{
#include <vector>
typedef std::vector<int> IntVector;
}}
class noncobjectIntVector;
packetFooPacket {
IntVector addresses;
};在
.msg
中使用abstract定义参数1
2
3
4
5packetFooPacket{
@customize(true);
abstract intfoo[];
std::vector<int>abstract intbar[]
}
方法二中编译器生成c++文件时会只生成纯虚函数。