一、概述
1.CommonAPI C++是什麼?
CommonAPI C++是用於開發分佈式應用程序的標準C++ API規範,該分佈式應用程序通過中間件進行進程間通信。
2.CommonAPI C++的目的是什麼?
CommonAPI C++依靠FrancaIDL來描述靜態接口,根據通信協議部署參數,一起組建完整的實例依賴關係模型。目的是封裝通信協議和相鄰的中間件,使應用程序的C++接口獨立於底層IPC堆棧。
也就是IPC Common API允許針對開發的應用程序(即使用C++的客戶端和服務器)可以與不同的IPC後端鏈接(someip,或D-Bus),而無需更改應用程序代碼。因此,爲使用特定IPC X(例如someip)的系統開發的組件可以輕鬆地部署到另一個使用IPC Y(例如D-Bus)的系統,只需要交換IPC Common API後端(someip或D-Bus),而無需重新編譯應用程序代碼。
實際的接口定義將使用Franca IDL創建(*.fild文件)。
而各項部署根據部署文件定義(*.fdepl文件)。
3.CommonAPI的組成原理
(1)基本原理如下圖所示:
- CommonAPI C++分爲獨立於中間件的部分(CommonAPI Core,僅僅指CommonAPI
接口)和特定於中間件的部分(CommonAPI Binding,用於選擇使用的IPC協議的代碼)。 - CommonAPI將接口描述語言Franca IDL用於接口規範(邏輯接口規範,*.fidl文件)。Franca IDL的代碼生成的是CommonAPI的組合部分。主要指邏輯接口的變量部分,那是接口的一部分,它取決於Franca IDL文件中的規範(數據類型,數組,枚舉和就基礎知識,包括屬性,方法,回調,錯誤處理,廣播)。
- CommonAPI C++ binding的代碼生成器需要特定於中間件的參數(部署參數,例如String數據類型的編碼/解碼格式)。這些參數在Franca部署文件(*.fdepl)中定義。主要獨立於接口規範。
(2)CommonAPI進一步劃分
CommonAPI的用戶API分爲兩部分:
- 基於FrancaIDL的生成部分,其中包含與FrancaIDL文件的類型,屬性和方法有關的API函數。也就是根據*.fidl文件生成的API函數。
- “公共”部分(Runtime API),其中包含用於加載運行時環境,創建proxy等的API函數。也就是根據*.fidl文件與*.fdepl文件生成的代碼中所包含的頭文件所鏈接的庫(CommonAPI lib files + CommonAPI someip/d-bus lib files)。
這張圖片更詳細地顯示了CommonAPI C++的元素如何組合在一起。注意:
- 用戶API的絕大多數是CommonAPI的生成部分。
- CommonAPI Core和IPC堆棧之間沒有直接關係。
- CommonAPI binding的生成代碼具有CommonAPI其他部分的所有接口。
4.CommonAPI基本的工作流程
CommonAPI需要基本的工作流程才能創建可執行的應用程序。
應用程序開發人員的工作流程如下:
-
創建具有方法和屬性的接口規範的FrancaIDL文件。
-
通過啓動CommonAPI代碼生成器爲客戶端和服務端生成代碼。
-
通過實現所生成框架中的方法來實現服務;或設置爲默認實現。
-
在應用程序中通過創建proxy並使用proxy調用這些方法來實現客戶端。
5.構建CommonAPI項目庫
CommonAPI可執行文件通常由6部分組成:
- 應用程序代碼本身是由開發人員手動編寫的;
- 生成的CommonAPI(綁定獨立)代碼。根據*.fidl文件生成的代碼。
在客戶端,這段代碼包含proxy函數,由應用程序調用;在服務中,它包含生成的函數,這些函數必須由開發人員手動實現(也可以生成默認實現)。 - CommonAPI運行時庫。
- 生成的綁定特定代碼(所謂的粘合代碼)。根據*.fdepl文件生成的代碼。
- 綁定的運行時庫。
- 使用的中間件的通用庫(例如libdbus/vsomeip)。
可以將這6部分劃分爲共享庫或靜態庫並將它們集中到目標平臺上。
現在將在創建proxy的確切時間加載粘合代碼庫。通過CommonAPI配置文件可以找到正確的庫,該配置文件包含CommonAPI地址和粘合代碼庫之間的關聯。如果配置文件中沒有條目,則使用默認設置。
膠水代碼庫是binding特定的;這意味着所需的運行庫由運行時鏈接程序自動加載。
二、CommonAPI C++規範
1.CommonAPI的基礎部分
Common API可以分爲兩部分:
-
第一部分是由Common
API代碼生成器生成的基於Franca的部分,也就是根據*.fidl文件生成的部分。那是接口的一部分,它是根據Franca
IDL文件中的規範生成的,指數據類型,數組,枚舉和接口等基礎知識,包含屬性,方法,回調,錯誤處理,廣播等方面。 -
第二個固定部分,是基於CommonAPI
Runtime的功能,且獨立於接口的規範。它們主要與基於中間件(someip/d-bus)提供的運行時環境有關。此外,此部分包含常見的類型定義和基類。也就是CommonAPI源代碼庫與所選中間件(someip/d-bus)的源代碼庫,供代碼生成器生成的代碼調用。通用API運行時是從其開始所有類加載的基類。通用API運行時訪問配置文件,以確定應加載哪個特定的中間件運行時庫。中間件庫是靜態鏈接的,或者是作爲共享庫(文件擴展名.so)提供的,因此可用動態加載它們。
2.Franca 基礎部分(*.fidl文件)
2.1*.fild文件的基本構成
類別1 | 類別2 | 說明 | 舉例 |
---|---|---|---|
package | 限定包名,與命名空間(namespace)有關,必須包含 | Package commonapi.examples | |
interface | 接口,提供一個接口名稱,用於包含接口函數等,當定義接口時需要 | Interface Methods | |
version | 版本號,同命名空間(namespace)有關,必須包含 | version{major 0 minor 1} | |
method | 方法,定義供應用程序所調用的輸入輸出接口函數,具有in,out,error三種參數,這三種參數都是可選的,可以只有in和out,或只有in等多種組合。 | method foo { in { Int32 x1 String x2 } out { Int32 y1 String y2} error{ stdErrorTypeEnum } } | |
broadcast | 廣播,定義供應用程序調用的廣播類接口函數;只有out參數。 | broadcast myStatus { out { Int32 myCurrentValue } } | |
attribute | 屬性,對各種屬性進行定義,可用於獲取或設置屬性值 | attribute Int32 x | |
typedef | 定義類型別名 | typedef MyType is Int32 | |
array | 數組 | array myArray of UInt16 | |
enumeration | 枚舉類型 | enumeration stdErrorTypeEnum { NO_FAULT MY_FAULT } | |
union | 聯合類型 | union MyUnion {UInt32 MyUIntString MyString} | |
struct | 結構體 | struct a2Struct { Int32 a Boolean b Double d} | |
map | 一種STL關聯容器,以一種鍵值-對的機制存儲數據 | map MyMap {UInt32 to String} | |
typeCollection | 類型集合,用戶根據自己的需要添加的數據類型的集合,各種數據結構在同一個文件中進行擴展等 | typeCollection CommonTypes | |
version | 同interface::version | 同interface::version | |
typedef | 同interface::typedef | 同interface::typedef | |
array | 同interface::array | 同interface::array | |
enumeration | 同interface::enumeration | 同interface::enumeration | |
union | 同interface::union | 同interface::union | |
struct | 同interface::struct | 同interface::struct | |
map | 同interface::map | 同interface::map |
2.2命名空間
Common API基本函數的名稱空間是Common API;Common API應用程序的名稱空間取決於Franca IDL中定義接口規範和接口版本的限定包名。
在名稱空間的開頭添加版本的主要原因是,我們將接口的名稱以及包路徑(完全限定名稱)作爲一個單元,這是在Franca文件中指定的。此名稱空間不應被中間的附加內容破壞。
Franca IDL
CommonAPI C++
namespace 在每個文件的開頭都有,代表這個文件所在的src-gen下面的路徑,每個namespace代表一層目錄;
如果接口沒有版本,則省略名稱空間中與版本有關的部分(例如圖中的namespace v0)。
Version {major 1 minor 0} -- namespace v1 { }
Version {major 0 minor 1} -- namespace v0 { }
Version {major 0 minor 0} -- 無與版本相關的namespce
2.3接口interface
對應Franca接口名稱(稱爲interfacename),將interfacename生成爲一個提供getInterfaceName()方法和getInterfaceVersion()方法的類。版本映射到CommoAPI::Version。
Franca IDL
CommonAPI C++
版本結構的規範是CommonAPI的一部分:
2.4類型集合Type Collection
在Franca中,可以將一組用戶定義的類型定義爲type collection。類型集合的名稱稱爲typecollectionname,可以爲空。CommonAPI爲空類型集合使用默認名稱Anonymous。CommonAPI代碼生成器生成頭文件Anonymous.hpp,併爲類型集合創建C++ struct。如果類型集合的名稱不爲空(例如:CommonTypes),則CommonAPI代碼生成器生成頭文件CommonTypes.hpp。
生成的函數類似於接口interface。
Franca IDL
CommonAPI C++
注意:在內部Franca模型中,類型集合是接口的基類。類型集合也可以有一個版本。在這種情況下,名稱空間就像生成的版本名稱一樣被擴展。
2.5方法Method
方法具有in和out參數,並且可以返回可選的應用程序錯誤error。如果指定了附加標誌fireAndForget,則不允許使用out參數,它指示既不返回值也不表示調用狀態。沒有fireAndForget標誌的方可能返回error,可以在Franca IDL中將其指定爲枚舉。
對於沒有fireAndForget標誌的方法,提供了一個附加的返回值CallStatus,它被定義爲枚舉:
在CallStatus定義了呼叫的傳輸層的結果,即它返回:
不鼓勵在沒有定義超時的情況下發送任何方法調用。可以通過將可選參數CallInfo傳遞給方法調用或在CommonAPI部署文件中配置超時。
該結構包含一個附加成員sender_,該成員可用於標識此函數的調用方。
標誌 | 參數 | 說明 |
---|---|---|
None | In + out + error(可選) | 提供一個附加的返回值CallStatus |
fireAndForget | in | 不允許使用out參數,指示既不返回也不表示調用狀態 |
Franca IDL
Method CommonAPI C++
Proxy
返回類型 | 函數名稱 | 參數 |
---|---|---|
virtual void | foo | const int32_t &_x1, const std::string &_x2, CommonAPI::CallStatus &_internalCallStatus, Methods::fooError &_error, int32_t &_y1, std::string &_y2, const CommonAPI::CallInfo *_info = nullptr |
virtual std::futureCommonAPI::CallStatus | fooAsync | const int32_t &_x1, const std::string &_x2, fooAsyncCallback _callback = nullptr, const CommonAPI::CallInfo *_info = nullptr |
virtual void | newFoo | const std::string &_MessageName, CommonAPI::CallStatus &_internalCallStatus |
在Franca IDL中,方法的異步或同步調用之間沒有區別。CommonAPI將同時提供兩者。API的用戶可以決定他調用哪個變體。含有fireAndForget標誌的method,只有同步調用,沒有異步調用。
在proxy端生成的函數調用:
- 所有const參數都是該方法的輸入參數。
- 所有非const參數將被返回值填充。
- CallStatus將在方法返回時被填滿,並指明其中之一
Method CommonAPI C++
Stub
返回類型 | 函數名稱 | 參數 |
---|---|---|
virtual void | foo | const std::shared_ptrCommonAPI::ClientId _client, int32_t _x1, std::string _x2, fooReply_t _reply |
virtual void | newFoo | const std::shared_ptrCommonAPI::ClientId _client, std::string _MessageName |
在stub端,生成的函數是生成的stub的一部分,這些功能是純虛函數的。這意味着必須提供一個實現。此實現的框架可以由代碼生成器生成。函數調用的返回值包裝在一個函數對象中:
typedef std::function<void (Methods::fooError _error, int32_t _y1, std::string _y2)>fooReply_t;
這允許它將此對象傳遞給其他函數,以便在stub端實現異步行爲。
在stub端,傳遞了ClientId類型的附加參數。ClientId標識向stub發送調用的客戶端。它用於在stub中標識調用者,並且應該由中間件添加,可以使用==操作符進行比較。
2.6廣播Broadcast
廣播只能有out參數。對於廣播,可以定義一個附加標誌selective。該標誌指示該消息不應該發送給所有註冊的參與者,而是該服務進行選擇,表示只有選定的客戶端才能在廣播中註冊。
標誌 | 參數 | 說明 |
---|---|---|
None | Out | 表示發送給所有註冊的參與者 |
Selective | Out | 該標誌表示只有服務選定的客戶端才能在廣播中註冊 |
Franca IDL
Broadcast CommonAPI C++
Proxy
返回類型 | 函數名稱 | 參數 |
---|---|---|
virtual MyStatusEvent & | getMyStatusEvent | |
virtual StatusSpecialSelectiveEvent & | getStatusSpecialSelectiveEvent |
這些方法返回一個事件的包裝類,該事件提供對廣播MyStatus的訪問。包裝類提供訂閱和取消訂閱的方法。Private屬性delegate_用於將函數調用轉發到特定的綁定(也就是用於與someip協議關聯)。
Broadcast CommonAPI C++
Stub
返回類型 | 函數名稱 | 參數 | 說明 |
---|---|---|---|
virtual void | fireMyStatusEvent | const int32_t &_myCurrentValue | |
virtual void | fireStatusSpecialSelective | const int32_t &_NewCurrentValue, const std::shared_ptrCommonAPI::ClientIdList _receivers = nullptr | |
virtual std::shared_ptrCommonAPI::ClientIdList const | getSubscribersForStatusSpecialSelective | ||
virtual void | onStatusSpecialSelectiveSubScriptionChanged | conststd::shared_ptrCommonAPI::ClientId _client, const CommonAPI::SelectiveBroadcastStubscriptionEvent _event | 鉤子方法,分別對選擇性廣播的新訂閱或已刪除訂閱作出反應 |
virtual bool | onStatusSpecialSelectiveSubscriptionRequest | const std::shared_ptrCommonAPI::ClientId _client | 鉤子方法,用於響應接受或拒絕新訂閱生成的stub提供觸發廣播(fire*())的方法和一些掛鉤請注意,通過使用ClientId和提供的鉤子,Franca關鍵字selective僅在stub端實現 |
2.7屬性Attributes
接口的屬性由名稱和類型定義。另外,屬性的規範可以具有兩個標誌:
·noSubscriptions
·readonly
標誌的組合有四種可能:
標誌 | 說明 |
---|---|
none | 沒有附加任何標誌的標準屬性,默認允許所有內容 |
readonly | 只讀屬性 |
noSubscriptions | 不可觀察的屬性 |
readonly onSubscriptions | 不可觀察和不可寫的屬性 |
可觀察的屬性提供了一個ChangedEvent,可用於訂閱對該屬性的更新。此事件與所有其他事件完全一樣。
頭文件Attribute.h中定義了這四種類型的每種屬性的模板類。
Franca IDL
CommonAPI C++
Proxy
返回類型 | 函數名稱 | 參數 |
---|---|---|
virtual XAttribute& | getXAttribute |
僅考慮屬性時,stub端屬性的CommonAPI如上,該get函數必須由應用程序實現。
Stub
返回類型 | 函數名稱 | 參數 |
---|---|---|
virtual const int32_t & | getXAttribute | const std::shared_ptrCommonAPI::ClientId _client |
此外,CommonAPI定義了必要的回調來處理與IDL描述中爲interface定義的屬性相關的遠程設置事件。對於每個屬性,在類AttributesStubRemoteEvent中定義了兩個回調:
- 一個驗證回調,允許驗證請求的值並防止設置,例如無效的值
- 在屬性值更改後執行本地工作的操作回調
StubRemoteEvent
返回類型 | 函數名稱 | 參數 | 說明 |
---|---|---|---|
virtual bool | onRemoteSetXAttribute | const std::shared_ptrCommonAPI::ClientId_client, int32_t _value | 驗證回調 |
virtual void | onRemoteXAttributeChanged | 操作回調 |
類AttributesStubAdapter提供了一個用於發送廣播和可觀察屬性的更改通知的API,這個API可以在設置屬性時調用:
StubAdapter
返回類型 | 函數名稱 | 參數 | 說明 |
---|---|---|---|
virtual void | fireXAttributeChanged | const int32_t& x | 用於發送廣播和可觀察屬性的更改通知 |
CommonAPI代碼生成器生成的stub的默認實現將屬性定義爲stub類的私有屬性。可以通過getter和setter函數從stub實現中訪問此屬性。此外,用於stub實現的API提供了一些回調:
StubDefault
返回類型 | 函數名稱 | 參數 | 說明 |
---|---|---|---|
virtual const int32_t& | getXAttribute | 獲取屬性值 | |
virtual const int32_t& | getXAttribute | const std::shared_ptrCommonAPI::ClientId _client | 獲取屬性值 |
virtual void | setXAttribute | int32_t _value | 在stub實現時更改屬性值 |
virtual void | setXAttribute | const std::shared_ptrCommonAPI::ClientId _client, int32_t _value | 在stub實現時更改屬性值 |
virtual bool | trySetXAttribute | int32_t _value | 從客戶端更改給定值 |
virtual bool | validateXAttributeRequestedValue | const int32_t & _value | 阻止設置屬性的回調函數 |
virtual void | onRemoteXAttributeChanged | 通知該屬性已更改的回調函數 |
CommonAPI提供了屬性接口的基本實現和擴展機制。所謂擴展機制,就是因爲根據應用程序要求屬性個數的不同,而存在的一種通用方案,其中包括單個擴展,以便爲屬性提供任何其他功能(屬性擴展)。這將防止開發人員突然添加屬性,而緩存不足的情況。
擴展的基類定義在AttributeExtension.hpp中。
2.8事件events
事件爲遠程觸發的動作提供了一個異步接口。這涵蓋了FrancaIDL中的廣播,方法和屬性的更改,事件每個proxy還提供了一個可用性事件,可用於通知proxy狀態。事件提供了訂閱和取消訂閱的方法,該方法允許註冊和註銷回調。
事件類的公共接口的相關部分如下:
訂閱後,調用listener進行偵聽,然後在出現新事件(例如,屬性已更改)的任何時候被調用。
2.9數據類型
2.9.1基本類型
CommonAPI使用的整數數據類型在stdint.h中定義。
Franca Type Name | CommonAPI C++ Type | Notes |
---|---|---|
UInt8 | uint8_t | unsigned 8-bit integer(range 0…255) |
Int8 | int8_t | signed 8-bit integer(range -128…127) |
UInt16 | uint16_t | unsigned 16-bit integer(range 0…65535) |
Int16 | int16_t | signed 16-bit integer(range -32768…32767) |
UInt32 | uint32_t | unsigned 32-bit integer(range 0…4294967295) |
Int32 | int32_t | signed 32-bit integer(range -2147483648…2147473647) |
UInt64 | uint64_t | unsigned 64-bit integer |
Int64 | int64_t | signed 64-bit integer |
Boolean | bool | boolean value, which can take one of two values: false or true |
Float | float | Floating point number(4 bytes, range +/3.4e+/-38, ~7 digits). |
Double | double | double precision floating point number(8 bytes, range+/-1.7e+/-308, ~15 digits). |
String | std::string | character string. |
ByteBuffer | std::vector<uint8_t> | buffer of bytes(aka BLOB). |
Franca只有一種字符串數據類型String,並且如有必要,可以通過部署模型(也就是*.fdepl文件)指定線路格式/編碼。
2.9.2數組Arrays
Franca數組類型(可以以顯式和隱式兩種方法表示)映射到std::vector。雖然可以使用typedef 將Franca IDL中給出的名稱顯式定義爲數組類型,但隱式版本將僅在需要是生成std::vector。
Franca IDL
CommonAPI C++
2.9.3結構體Structures
Franca struct類型映射到C++ struct類型。
Structures映射到從CommonAPI::Struct繼承的struct。CommonAPI::Struct將結構化數據保存在tuple中。生成的類爲結構成員提供getter和setter方法。
Franca IDL
CommonAPI C++
2.9.4枚舉Enumerations
Franca枚舉將映射到從基類繼承的C++結構CommonAPI::Enumeration。默認情況下,Enum支持的數據類型和連接格式爲uint32_t。如果需要,可以通過CommonAPI部署文件*.fdepl文件(枚舉支持類型)指定連接格式。
Franca IDL
CommonAPI C++
2.9.5Map
出於效率原因,Franca映射的Common API數據類型爲std::unordered_map<K, V>。
Franca IDL
CommonAPI C++
2.9.6聯合Union
Franca 中定義的聯合類型被實現爲CommonAPI通用模板化C++ variant類的類型定義。
Franca IDL
CommonAPI C++
2.9.7類型別名Type Aliases
Franca typedef映射到C++ typedef。
Franca IDL
CommonAPI C++
3.CommonAPI的部署方式(*.fdepl文件)
- 定義獨立於中間件(vSomeIp/D-Bus)的C++ API的一個問題是,需要針對API的各個部分使用不同的配置參數,這部分需要取決於中間件。例如,參數,數組或字符串的最大長度等。
- Franca IDL可以根據中間件或特定於平臺的部署模型(*.fdepl文件)中使用的中間件來指定部署參數。
- 一個明確的目標是,針對Common API編寫的應用程序可以與不同的Common API IPC後端鏈接,而無需更改應用程序代碼。
- 因此,有一個重要的隱性限制:Franca IDL(**.fidl文件)中定義的接口只與CommonAPI以及用戶調用相關。專用於IPC後端的部署模型(*.fdepl)不得影響所生成的API。但是允許使用非特定的部署模型。
3.1CommonAPI部署
CommonAPI代碼生成器幾乎支持FrancaIDL的全部功能,並且無需任何部署文件即可工作。但是,可以根據以下部署規範,不僅爲綁定而且爲CommonAPI本身編寫接口規範的部署文件。
可以在CommonAPI C++級別上設置枚舉支持類型,不僅針對單個枚舉,而且通常針對整個接口。請注意,綁定也可能具有與枚舉的支持類型有關的部署設置。
也可以定義函數調用的超時時間。設置此超時的另一種可能性是在方法調用的可選參數中對CallInfo進行定義。
代碼生成器不評估實例和提供者的設置。
有關部署參數的用法,請參見下方,CommonAPI本身的所有部署參數都是可選的。
3.2*.fdepl文件的基本構成
類別1 | 類別2 | 說明 | 舉例 |
---|---|---|---|
for interface | 對接口進行一些部署,設置ServiceID值,也可以設置枚舉支持的類型 | *Reliable = false表示使用UDP協議,Reliable = true表示使用TCP協議 | |
attribute | 爲屬性的getter, setter等方法提供ID值 | attribute x { SomeIpGetterID = 3000 SomeIpSetterID = 3001 SomeIpNotifierID = 33010 SomeIpEventGroups = { 33010 } SomeIpGetterReliable = false SomeIpSetterReliable = false SomeIpNotifierReliable = false} | |
method | 設置method的ID值,並設置輸入輸出字符串類型的編碼/解碼格式;也可以訂閱方法調用的超時 | method foo { SomeIpMethodID = 30000 SomeIpReliable = false in { x2 { SomeIpStringEncoding = utf16le } } out { y2 {SomeIpStringEncoding =utf16le} } } | |
broadcast | 設置廣播事件以及廣播事件組的ID值,並設置輸出字符串類型的編碼/解碼格式 | broadcast myStatus { SomeIpEventID = 33020 SomeIpEventGroups = { 33020 } } | |
array | 定義數組的長度 | SomeIpArrayLengthWidth = 2 | |
enumeration | 設置枚舉的數據類型 | EnumBackingType = UInt64 | |
for provider | 提供實例 | ||
instance | 設置實例名稱以及實例ID值,並設置實例的地址和端口號 | instance commonapi.mthd.Method { InstanceId = “commonapi.mthd.Method” SomeIpInstanceID = 22136 SomeIpUnicastAddress = “192.168.0.2” SomeIpReliableUnicastPort = 30500 SomeIpUnreliableUnicastPort = 30501 } | |
for typeCollection | 用戶自己定義的各種數據類型的集合 | ||
array | 定義數組的長度 | SomeIpArrayLengthWidth = 2 | |
enumeration | 設置枚舉的數據類型 | EnumBackingType = UInt64 |
3.2for interface
for interface,對應於*.fidl文件中的interface,在這裏面主要是配置中間件的ServiceID,以及其他method,broadcast,attribute等使用的methodID,eventID值等。
設置ServiceID:
SomeIpServiceID = 4660
也可以在此定義整個接口的CommonAPI C++級別上定義枚舉支持的類型,默認是UInt32:
DefaultEnumBackingType: { UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64 } (default: UInt32);
例如:
DefaultEnumBackingType = UInt8
3.2.1attribute
爲每個屬性所使用的getter, setter等方法設置ID值,並設置這些方法的可靠性。
3.2.2method
爲方法method設置methodID值,並設置可靠性,也可以爲in, out的輸入輸出參數的字符串類型設置編碼/解碼格式,也可以不設置,從而使用默認設置。
也可以在此處設置超時:
Timeout : Integer (default: 0);
例如:
Timeout = 1
3.2.3broadcast
爲broadcast事件設置EventID值,Event Groups值(這個是將自己想要劃分爲一組的事件ID寫在一起),設置可靠性,也可以定義out參數裏面字符串類型的編碼/解碼格式。
3.3for typeCollection
3.3.1array
根據*.fidl文件中使用的數組的個數,來設置數組的長度。
例如,當*.fidl中使用了兩個數組:
attribute myArray myArraySpecific
attribute myArray myArrayDefault
在*.fdepl部署文件中將數組的長度定義爲2:
array myArray {
SomeIpArrayLengthWidth = 2
}
3.3.2enumeration
可以在此設置枚舉使用的數據類型:
EnumBackingType : {UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64} (optional);
例如:
EnumBackingType = UInt64
3.4for provider
在此提供程序所依賴的所有服務實例(如果有),併爲實例設置名稱,ID值以及IP地址和端口號。
三、應用程序編寫
開發CommonAPI應用程序的第一步可能是客戶端將用於與服務器通信的接口的定義。在CommonAPI的上下文中,無論最終打算使用哪種通信機制,此接口的定義始終通過Franca IDL進行。
根據*.fidl文件與*.fdepl文件生成的代碼文件,具體分爲以下幾部分,以及各部分的功能。
**.fidl文件生成的接口代碼 | ||
---|---|---|
HelloWorld.hpp | 用於客戶端開發:代理是一個提供方法調用的類,該方法調用將導致對服務的遠程方法調用,以及服務可以廣播的事件的註冊方法。 | |
HelloWorldProxy.hpp | ||
HelloWorldProxyBase.hpp | ||
HelloWorldStub.hpp | 服務器開發:存根是服務的一部分,當來自客戶端的遠程方法調用到達時,存根將被調用,它還包含將事件(廣播)激發到幾個或所有客戶端的方法。 | |
HelloWorldStubDefault.hpp | ||
HelloWorldStubDefault.cpp | ||
*.fdepl文件生成的粘合代碼 | 名稱中具有綁定名稱(例如someip)的所有文件都是綁定所需的粘合代碼,並且在開發應用程序時不相關,它們僅需與應用程序一起編譯 | |
HelloWorldSomeIPDeployment.hpp | ||
HelloWorldSomeIPDeployment.cpp | ||
HelloWorldSomeIPProxy.cpp | ||
HelloWorldSomeIPProxy.hpp | ||
HelloWorldSomeIPStubAdapter.hpp | ||
HelloWorldSomeIPStubAdapter.cpp |
這屬於代理/存根結構,通過這張流程圖,很容易發現CommonAPI實現IPC其實是在原來的C/S框架上加入了代理/存根結構。
具體的編寫參考例子:https://blog.csdn.net/C_Silence_K/article/details/104674945
四、參考資料
1.CommonAPI+someip的配置與使用,操作流程,用HelloWorld演示
https://at.projects.genivi.org/wiki/pages/viewpage.action?pageId=5472311
2.CommonAPI C++規範
https://docs.projects.genivi.org/ipc.common-api-tools/3.1.3/html/CommonAPICppSpecification.html
3.CommonAPI C++用戶指南
https://docs.projects.genivi.org/ipc.common-api-tools/3.1.3/html/CommonAPICppUserGuide.html
4.CommonAPI C++的使用例子
https://github.com/GENIVI/capicxx-core-tools/tree/master/CommonAPI-Examples