(四) 10分钟搞定fidl语法

本片文章主要用来介绍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;

注释的写法:

//注释内容
<** 注释内容 **>

你可能感兴趣的:(SOMEIP,someip,SOME/IP,vsomeip,CommonAPI,commonapi,fidl)