(四) 10分钟搞定fidl语法

本片文章主要用来介绍CommonAPI中的接口描述语言fidl与fdepl文件的基本语法。

基础数据类型

数据名数据含义取值范围
UInt8unsigned 8-bit integer0 - 255
Int8signed 8-bit integer-128 - 127
UInt16unsigned 16-bit integer0…65535
Int16signed 16-bit integer-32768 - 32767
UInt32unsigned 32-bit integer0 - 4294967295
Int32signed 32-bit integer-2147483648 - 2147483647
UInt64unsigned 64-bit integer
Int64signed 64-bit integer
Integergeneric integer
BooleanBoolean 类型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;

注释的写法:

//注释内容
<** 注释内容 **>
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
fidl (Fast Inter-process Communication Interface Definition Language) 是一种用于定义跨进程通信接口的语言,支持多种不同的编程语言和平台。vsomeip 库提供了对 fidl 语言的支持,可以使用 fidl 定义服务接口,并使用 vsomeip 实现跨进程通信。以下是一个简单的 vsomeip fidl 使用范例代码,用于实现一个简单的服务和客户端应用。这个例子是基于 C++ 的,使用了 vsomeip 库。 服务端代码: ```c++ #include <iostream> #include <vsomeip/vsomeip.hpp> #include "hello-service.fidl.h" class my_service : public fidl::hello_service { public: my_service() : fidl::hello_service("my_service") {} virtual std::string say_hello(const std::string& name) override { std::cout << "Received a request: " << name << std::endl; return "Hello, " + name + "!"; } }; int main() { vsomeip::runtime_impl my_runtime; my_service my_service_instance; my_runtime.add_service(my_service_instance); my_runtime.offer_service("fidl-hello"); my_runtime.start(); return 0; } ``` 客户端代码: ```c++ #include <iostream> #include <vsomeip/vsomeip.hpp> #include "hello-service.fidl.h" int main() { vsomeip::runtime_impl my_runtime; vsomeip::client my_client("my_client"); my_client.request_service("fidl-hello"); my_client.initialize(); fidl::hello_service_proxy my_service_proxy(my_client); auto response = my_service_proxy.say_hello("world"); std::cout << "Received a response: " << response << std::endl; my_client.release_service("fidl-hello"); my_client.deinitialize(); return 0; } ``` 这个例子实现了一个简单的服务和客户端应用,服务端使用 fidl 定义了一个名为 "say_hello" 的方法,客户端使用 fidl 代理来调用这个方法并打印出响应。需要注意的是,fidl 文件需要使用 fidl-cxx 工具生成相应的 C++ 代码,这个工具可以从 fidl-tools 项目中获取。另外,fidl 语言支持异步调用和事件通知等高级特性,可以根据具体需求进行适当的扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值