本片文章主要用来介绍CommonAPI中的接口描述语言fidl与fdepl文件的基本语法。
数据名 | 数据含义 | 取值范围 |
---|---|---|
UInt8 | unsigned 8-bit integer | 0 - 255 |
Int8 | signed 8-bit integer | -128 - 127 |
UInt16 | unsigned 16-bit integer | 0…65535 |
Int16 | signed 16-bit integer | -32768 - 32767 |
UInt32 | unsigned 32-bit integer | 0 - 4294967295 |
Int32 | signed 32-bit integer | -2147483648 - 2147483647 |
UInt64 | unsigned 64-bit integer | |
Int64 | signed 64-bit integer | |
Integer | generic integer | |
Boolean | Boolean 类型 | true / false |
Float | 浮点类型 | +/- 3.4e +/- 38, ~7 |
Double | 双精度浮点类型 | +/- 1.7e +/- 308,~15 |
String | 字符串 | 无 |
ByteBuffer | 二进制流 | 无 |
Integer
可以指定取值范围的整形
Integer
Integer(1,7)
Integer(-20,100)
Integer(0,maxInt)
Integer(minInt,maxInt)
在fidl中可以定义如下:
attribute Integer(-32, 50) Temp
最后通过CommonAPI转成的是如下的属性类型:
CommonAPI::RangedInteger<-32, 50>
array
数组类型,在fidl中存在两种定义模式,一个是显示定义,一个是隐式定义,显示定义可以指定数组名称,如下:
interface IInterface {
version { major 0 minor 1 }
attribute Students StudentsList
array Students of String
}
通过CommonAPI转换后,会生成如下:
//StudentList属性生成如下:
CommonAPI::ObservableAttribute<::v0::com::commapi::test::IWeatherService::Students> StudentsListAttribute;
//Students 数组定义如下
typedef std::vector< std::string> Students;
当然也可以隐式的直接定义,如下:
interface IInterface {
version { major 0 minor 1 }
attribute String[] StudentsList
}
这样子,就不会存在typedef去重命名数据类型了,生成代码如下:
CommonAPI::ObservableAttribute<std::vector< std::string >> StudentsListAttribute;
enumeration
枚举类型
interface IInterface {
version { major 0 minor 1 }
enumeration ClassType {
A_Type,
B_Type,
C_Type
}
}
转换后的代码
struct ClassType : CommonAPI::Enumeration< uint8_t> {
enum Literal : uint8_t {
A_Type = 0,
B_Type = 1,
C_Type = 2
};
...
...
}
也可以指定值
interface IWeatherService {
version { major 0 minor 1 }
enumeration ClassType {
A_Type = 100,
B_Type = 101,
C_Type = 102
}
}
转成代码:
struct ClassType : CommonAPI::Enumeration< uint8_t> {
enum Literal : uint8_t {
A_Type = 100,
B_Type = 101,
C_Type = 102
};
...
...
}
enumeration是可以继承的,写法如下:
interface IInterface{
version { major 0 minor 1 }
enumeration ClassType {
A_Type = 100,
B_Type = 101,
C_Type = 102
}
enumeration ClassSubType {
D_TYPE = 104,
E_TYPE = 105
}
}
转成代码后,ClassType如上所示,ClassSubType如下:
struct ClassSubType : CommonAPI::Enumeration< uint8_t> {
enum Literal : uint8_t {
A_Type = 100,
B_Type = 101,
C_Type = 102,
D_TYPE = 104,
E_TYPE = 105
};
}
这里需要注意的是,fidl的extends生成的枚举是两个不同的结构体,两者之间不存在上下级关系
struct
结构体,可以理解为C++中的struct关键字
interface IInterace {
version { major 0 minor 1 }
struct Person {
String name
UInt8 age
}
}
转成后的C++代码
struct Person : CommonAPI::Struct< std::string, uint8_t> {
Person()
{
std::get< 0>(values_) = "";
std::get< 1>(values_) = 0u;
}
Person(const std::string &_name, const uint8_t &_age)
{
std::get< 0>(values_) = _name;
std::get< 1>(values_) = _age;
}
...
...
};
同样struct在fidl中也是可以继承的,如下:
interface IWeatherService {
version { major 0 minor 1 }
struct Person {
String name
UInt8 age
}
struct Women extends Person {
Boolean kind_girl
}
}
生成的代码中,Person结构保持不变,Women与Person实际没有任何关系,只是fidl根据Person中的参数复制过来在Women结构体中生成
struct Women : CommonAPI::Struct< std::string, uint8_t, bool> {
Women()
{
std::get< 0>(values_) = "";
std::get< 1>(values_) = 0u;
std::get< 2>(values_) = false;
}
Women(const std::string &_name, const uint8_t &_age, const bool &_kind_girl)
{
std::get< 0>(values_) = _name;
std::get< 1>(values_) = _age;
std::get< 2>(values_) = _kind_girl;
}
...
...
}
当然,我们也可以让Women跟Person生成的结构体具备上下级关系,只需要在Person中添加polymorphic
关键字即可
interface IWeatherService {
version { major 0 minor 1 }
struct Person polymorphic {
String name
UInt8 age
}
struct Women extends Person{
Boolean kind_girl
}
}
转成的代码就是这样了:
struct Person : CommonAPI::PolymorphicStruct {
static COMMONAPI_EXPORT std::shared_ptr< Person> create(CommonAPI::Serial _serial);
CommonAPI::Serial getSerial() const { return PERSON_SERIAL; }
...
...
}
struct Women : Person {
CommonAPI::Serial getSerial() const { return WOMEN_SERIAL; }
Women()
: Person()
{
std::get< 0>(values_) = false;
}
Women(const std::string &_name, const uint8_t &_age, const bool &_kind_girl)
: Person(_name, _age)
{
std::get< 0>(values_) = _kind_girl;
}
...
....
}
union
联合体,这个跟C/C++中的union关键字还不一样,对应生成的是一个std::tuple
数据结构
interface IInterface {
version { major 0 minor 1 }
union Name {
String name1
String name2
}
}
转成C++后
typedef CommonAPI::Variant< std::string, std::string> Name;
class Variant {
private:
typedef std::tuple_size<std::tuple<Types_...>> TypesTupleSize;
}
map
键值对
interface IWeatherService {
version { major 0 minor 1 }
map Student{
String to UInt8
}
}
转成C++后,是一个unordered_map的键值对
typedef std::unordered_map< std::string, uint8_t> Student;
typedef
这个基本就跟c++中的typedef作用一致,类型重命名
interface IInterface {
version { major 0 minor 1 }
array nmea of Double
typedef GpsData is nmea
}
转换如下:
typedef std::vector< double> nmea;
typedef nmea GpsData;
const Boolean b1 = true
const UInt32 MAX_COUNT = 10000
const String foo = "bar"
const Double pi = 3.1415d
转换后如下:
const bool b1 = true;
const uint32_t MAX_COUNT = 10000;
const std::string foo = "bar";
const double pi = 3.1415;
array Array1 of UInt16
const Array1 empty = []
const Array1 full = [ 1, 2, 2+3, 100 * 100+100 ]
struct Struct1{
Boolean e1
UInt16 e2
String e3
}
const Struct1 s1 = {e1: true, e2: 1, e3: "foo"}
union Union1 {
UInt16 e1
Boolean e2
String e3
}
const Union1 uni1 = { e1: 1 }
const Union1 uni2 = { e3: "foo" }
map Map1 { UInt16 to String }
const Map1 m1 = [ 1 => "one", 2 => "two" ]
interface
类似于我们写java的class或者interface,包裹了该服务的主要逻辑, Interface逻辑体也是可以继承的,且具备上下级关系。
interface Base {
version { major 0 minor 1}
const String name = "aaa"
}
interface IInterface extends Base {
version { major 0 minor 1}
const UInt8 age = 12
}
转成后:
class Base {
public:
virtual ~Base() { }
static inline const char* getInterface();
static inline CommonAPI::Version getInterfaceVersion();
const std::string name = "aaa";
};
class IInterface
: virtual public Base {
public:
virtual ~IInterface() { }
static inline const char* getInterface();
static inline CommonAPI::Version getInterfaceVersion();
const uint8_t age = 12;
};
attribute
属性定义,这个就是咱们写代码过程中的变量
定义格式:
普通属性:attribute [数据类型] [属性名]
只读属性:attribute [数据类型] [属性名] readonly
只读且不可订阅属性:attribute [数据类型] [属性名] readonly noSubscriptions
method
方法,定义的就是咱们写代码时候的函数,函数可定义入参出参
interface IInterface{
version { major 0 minor 1}
attribute String name readonly
//修改名称
method changeName {
in {
//入参是新名称
String newName
}
out {
//修改结果
Boolean changed
}
//定义服务端方法执行出错无法正确返回值的时候的错误Code
error{
DIVISION_BY_ZERO
OVERFLOW
UNDERFLOW
}
}
}
broadcast
事件通知,主要用来通知订阅方当前事件已触发
interface IInterface{
version { major 0 minor 1}
attribute String name readonly
broadcast HighTemp{
out{
UInt32 eventID
String eventName
}
}
}
转码后
typedef CommonAPI::Event<uint32_t, std::string> HighTempEvent;
注释的写法:
//注释内容
<** 注释内容 **>