中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

河南網(wǎng)站備案系統(tǒng)短信b站視頻推廣網(wǎng)站2023

河南網(wǎng)站備案系統(tǒng)短信,b站視頻推廣網(wǎng)站2023,比價(jià)網(wǎng)官網(wǎng),網(wǎng)上購(gòu)物商城網(wǎng)址一. 概述 ? 這篇文章主要是想整理并且分析CommonAPI代碼生成工具根據(jù)fidl和fdepl配置文件生成出來(lái)的代碼的結(jié)構(gòu)和作用。 二. fidl ? 用戶根據(jù)業(yè)務(wù)需求在fidl文件中定義業(yè)務(wù)服務(wù)接口的結(jié)構(gòu)以及自定義數(shù)據(jù)類型,然后使用core生成工具傳入fidl文件生成該fidl的核心…

一. 概述

? 這篇文章主要是想整理并且分析CommonAPI代碼生成工具根據(jù)fidl和fdepl配置文件生成出來(lái)的代碼的結(jié)構(gòu)和作用。

二. fidl

? 用戶根據(jù)業(yè)務(wù)需求在fidl文件中定義業(yè)務(wù)服務(wù)接口的結(jié)構(gòu)以及自定義數(shù)據(jù)類型,然后使用core生成工具傳入fidl文件生成該fidl的核心層Proxy和Stub以及配套的相關(guān)代碼。

? 例如官方范例上的HelloWorld(https://github.com/COVESA/capicxx-core-tools/blob/master/CommonAPI-Examples/E01HelloWorld/fidl/E01HelloWorld.fidl),使用生成工具commonapi-core-generator-linux-x86_64輸入該fidl文件可以生成HelloWorld.hpp,HelloWorldProxy.hpp,HelloWorldProxyBase.hpp,HelloWorldStub.hpp,HelloWorldStubDefault.hpp這5個(gè)代碼文件。

2.1 interface

? 一個(gè)fidl文件對(duì)應(yīng)一個(gè)CommonAPI的interface,對(duì)于C++來(lái)說(shuō),要定義一個(gè)interface,當(dāng)然是使用一個(gè)抽象類來(lái)定義了,這個(gè)抽象類就是HelloWorld.hpp文件中的HelloWorld類了。

namespace v1 {
namespace commonapi {class HelloWorld {
public:virtual ~HelloWorld() { }static inline const char* getInterface();                  // HelloWorld業(yè)務(wù)的CommonAPI接口名稱static inline CommonAPI::Version getInterfaceVersion();    // HelloWorld業(yè)務(wù)的CommonAPI接口版本
};const char* HelloWorld::getInterface() {return ("commonapi.HelloWorld:v1_0");
}CommonAPI::Version HelloWorld::getInterfaceVersion() {return CommonAPI::Version(1, 0);
}} // namespace commonapi
} // namespace v1

? 當(dāng)看到core工具生成的HelloWorld接口類,感覺(jué)有點(diǎn)奇怪,這個(gè)HelloWorld接口類只定義并且實(shí)現(xiàn)了兩個(gè)關(guān)于接口信息的函數(shù)(接口名稱和接口版本信息),而fidl中關(guān)于HelloWorld接口中的業(yè)務(wù)函數(shù)sayHello在生成的HelloWorld接口類中確沒(méi)有

// HelloWorld.fidl
package commonapiinterface HelloWorld {version {major 1 minor 0}method sayHello {    // 該函數(shù)沒(méi)有生成在HelloWorld接口類中in {String name}out {String message}}
}

? 對(duì)于為什么生成的HelloWorld接口類中沒(méi)有定義sayHello函數(shù)的原因,個(gè)人閱讀完生成的代碼后理解是,由于HelloWorld.fidl生成的核心層Proxy以及Stub代碼在sayHello函數(shù)上的定義是不兼容的,而HelloWorld接口類又是核心層HelloWorldProxy和HelloWorldStub的父類,因此無(wú)法將sayHello函數(shù)的申明放入HelloWorld接口類中。

? HelloWorld接口類中的getInterface和getInterfaceVersion函數(shù)是為了給CommonAPI核心層代碼庫(kù)創(chuàng)建核心層Proxy/Stub的時(shí)候使用的,代碼如下:

// 代碼文件/usr/local/include/CommonAPI-3.2/CommonAPI/Runtime.hpp
template<template<typename ...> class ProxyClass_, typename ... AttributeExtensions_>COMMONAPI_EXPORT std::shared_ptr<ProxyClass_<AttributeExtensions_...>>buildProxy(const std::string &_domain,const std::string &_instance,const ConnectionId_t &_connectionId = DEFAULT_CONNECTION_ID) {std::shared_ptr<Proxy> proxy= createProxy(_domain,//這里的ProxyClass就是HelloWorldProxy類,調(diào)用HelloWorldProxy的父類HelloWorld中的getInterfaceProxyClass_<AttributeExtensions_...>::getInterface(),   _instance,_connectionId);if (proxy) {return std::make_shared<ProxyClass_<AttributeExtensions_...>>(proxy);}return nullptr;}

?

2.2 Proxy

? 在核心層生成了HelloWorldProxy.hpp和HelloWorldProxyBase.hpp兩個(gè)代碼文件,里面分別定義了HelloWorldProxy和HelloWorldProxyBase兩個(gè)類。

? 其中,HelloWorldProxyBase是HelloWorldProxy的一個(gè)父類,其中包含了fidl中sayHello函數(shù)的相關(guān)定義(包括了同步調(diào)用和異步調(diào)用兩種)

class HelloWorldProxyBase: virtual public CommonAPI::Proxy {
public:typedef std::function<void(const CommonAPI::CallStatus&, const std::string&)> SayHelloAsyncCallback; // 異步調(diào)用的回調(diào)通知接口virtual void sayHello(std::string _name, CommonAPI::CallStatus &_internalCallStatus, std::string &_message, const CommonAPI::CallInfo *_info = nullptr) = 0;  // 同步調(diào)用接口virtual std::future<CommonAPI::CallStatus> sayHelloAsync(const std::string &_name, SayHelloAsyncCallback _callback = nullptr, const CommonAPI::CallInfo *_info = nullptr) = 0;  // 異步調(diào)用接口virtual std::future<void> getCompletionFuture() = 0;
};

? HelloWorldProxy類中實(shí)現(xiàn)了HelloWorldProxyBase父類中定義的sayHello相關(guān)接口:

template <typename ... _AttributeExtensions>
void HelloWorldProxy<_AttributeExtensions...>::sayHello(std::string _name, CommonAPI::CallStatus &_internalCallStatus, std::string &_message, const CommonAPI::CallInfo *_info) {delegate_->sayHello(_name, _internalCallStatus, _message, _info);
}

? 可以看到,HelloWorldProxy內(nèi)部實(shí)現(xiàn)fidl中定義的接口時(shí),還依賴了一個(gè)delegate_對(duì)象,這個(gè)delegatge_對(duì)象是HelloWorldProxyBase類型的共享指針

template <typename ... _AttributeExtensions>
class HelloWorldProxy: virtual public HelloWorld,virtual public HelloWorldProxyBase,virtual public _AttributeExtensions... {public:...private:std::shared_ptr< HelloWorldProxyBase> delegate_;
};

? 這里就有點(diǎn)不對(duì)了,前面說(shuō)過(guò)HelloWorldProxy的一個(gè)父類就是HelloWorldProxyBase,難道HelloWorldProxy對(duì)象內(nèi)部的這個(gè)delegate_共享指針是指向自己的?當(dāng)然不是,在src-gen目錄下查找還有沒(méi)有其他類是HelloWorldProxy,結(jié)果看到HelloWorldProxyBase類也是HelloWorldSomeIPProxy類的父類,HelloWorldSomeIPProxy是通過(guò)commonapi-someip-generator-linux-x86_64工具生成的綁定層的Proxy類。

? 也就是說(shuō)核心層的Proxy是依賴綁定層的Proxy的,綁定層的內(nèi)部會(huì)產(chǎn)生依賴所綁定中間件的代碼來(lái)實(shí)現(xiàn)fidl中定義的接口函數(shù)。

2.3 Stub

? 在核心層生成了HelloWorldStub.hpp,HelloWorldStubDefault.hpp這兩個(gè)代碼文件,其中包含HelloWorldStubAdapter,HelloWorldStubRemoteEvent, HelloWorldStub以及HelloWorldStubDefault這四個(gè)類,這四個(gè)類的關(guān)系如下:

? 首先是HelloWorldStubAdapter類,其繼承于CommonAPI::StubAdapter(實(shí)現(xiàn)了CommonAPI地址提供接口getAddress)和HelloWorld(實(shí)現(xiàn)了接口信息提供方法getInterfacegetInterfaceVersion)。

? 所謂CommonAPI地址,包含三個(gè)成員(domain, interface, instance),這三個(gè)成員都是字符串:

namespace CommonAPI {
class Address {
public:COMMONAPI_EXPORT Address();...private:std::string domain_;     // 所在域std::string interface_;   // 接口名稱std::string instance_;    // 實(shí)例名稱friend COMMONAPI_EXPORT std::ostream &operator<<(std::ostream &_out, const Address &_address);
};
}

? CommonAPI::StubAdapter中CommonAPI地址的來(lái)源是綁定層的StubAdapter(CommonAPI::SomeIP::StubAdapter)在初始化的時(shí)候賦值的

// Stub.hpp
namespace CommonAPI {class StubAdapter {public:virtual ~StubAdapter() {}inline const Address &getAddress() const { return address_; }protected:Address address_;  // 在綁定層的StubAdapter中賦值};
}// StubAdapter.cpp
namespace CommonAPI {
namespace SomeIP {
class StubAdapter: virtual public CommonAPI::StubAdapter, public InterfaceHandler {   // 繼承自核心層的StubAdapter
...
void
StubAdapter::init(std::shared_ptr<StubAdapter> instance) {(void) instance;// AddressTranslator保存了綁定層地址和核心層地址的映射關(guān)系// 這個(gè)映射關(guān)系在綁定層StubAdapter的initializer函數(shù)中插入的AddressTranslator::get()->translate(someipAddress_, address_);  // address_是CommonAPI::StubAdapter中的成員變量
}
...
}
}

? 其次是HelloWorldStubRemoteEvent類,這個(gè)類目前基本是空的,因?yàn)檫@是個(gè)和屬性相關(guān)的類,如果你的fidl中沒(méi)有定義屬性成員,那么生成的StubRemoteEvent類可能就是空的,對(duì)照官網(wǎng)上https://github.com/COVESA/capicxx-core-tools/tree/master/CommonAPI-Examples/E02Attributes這個(gè)帶屬性的范例生成的代碼可以看到,有屬性的fidl生成的StubRemoteEvent類是定義了一些屬性相關(guān)的接口的,例如:

class E02AttributesStubRemoteEvent
{
public:virtual ~E02AttributesStubRemoteEvent() { }/// Verification callback for remote set requests on the attribute xvirtual bool onRemoteSetXAttribute(const std::shared_ptr<CommonAPI::ClientId> _client, int32_t _value) = 0;/// Action callback for remote set requests on the attribute xvirtual void onRemoteXAttributeChanged() = 0;/// Verification callback for remote set requests on the attribute a1virtual bool onRemoteSetA1Attribute(const std::shared_ptr<CommonAPI::ClientId> _client, ::v1::commonapi::examples::CommonTypes::a1Struct _value) = 0;/// Action callback for remote set requests on the attribute a1virtual void onRemoteA1AttributeChanged() = 0;
};

? 也就是說(shuō),生成的這個(gè)StubRemoteEent類是個(gè)關(guān)于事件通知的接口類,是需要用戶自己來(lái)實(shí)現(xiàn)內(nèi)部接口來(lái)接收屬性的變化通知。

?

? 接者是HelloWorldStub類,這也是個(gè)接口類,繼承自CommonAPI::Stub,CommonAPI::Stub最重要的工作是和CommonAPI::StubHelper打交道

namespace CommonAPI {
template<typename StubAdapter_, typename StubRemoteEventHandler_>
class Stub: public virtual StubBase {
public:// 初始化StubAdaptervirtual StubRemoteEventHandler_* initStubAdapter(const std::shared_ptr<StubAdapter_> &_stubAdapter) = 0;// 返回StubAdapterinline const std::shared_ptr<StubAdapter_> getStubAdapter() const { return stubAdapter_.lock(); }protected:std::weak_ptr<StubAdapter_> stubAdapter_;

? 因此,HelloWorldStub類包含了初始化和返回StubAdapter的接口,此外還增加了fidl中sayHello接口的申明,也就是說(shuō)HelloWorldStub接口類的實(shí)現(xiàn)類至少要實(shí)現(xiàn)initStubAdapter,getStubAdapter和sayHello三個(gè)接口。

? 最后就是HelloWorldStubDefault類,它就是實(shí)現(xiàn)上面HelloWorldStub接口類中三個(gè)接口的實(shí)現(xiàn)類,代碼如下:

class COMMONAPI_EXPORT_CLASS_EXPLICIT HelloWorldStubDefault: public virtual HelloWorldStub {
public:COMMONAPI_EXPORT HelloWorldStubDefault(): remoteEventHandler_(this),interfaceVersion_(HelloWorld::getInterfaceVersion()) {}COMMONAPI_EXPORT const CommonAPI::Version& getInterfaceVersion(std::shared_ptr<CommonAPI::ClientId> _client) {(void)_client;return interfaceVersion_;  // 返回接口版本}COMMONAPI_EXPORT HelloWorldStubRemoteEvent* initStubAdapter(const std::shared_ptr< HelloWorldStubAdapter> &_adapter) {CommonAPI::Stub<HelloWorldStubAdapter, HelloWorldStubRemoteEvent>::stubAdapter_ = _adapter;return &remoteEventHandler_;}COMMONAPI_EXPORT virtual void sayHello(const std::shared_ptr<CommonAPI::ClientId> _client, std::string _name, sayHelloReply_t _reply) {(void)_client;(void)_name;std::string message = "";_reply(message);}...

? HelloWorldStubDefault類是一個(gè)默認(rèn)的生成的Stub接口實(shí)現(xiàn)類,里面的函數(shù)實(shí)現(xiàn)大多數(shù)是無(wú)用的,用戶需要在HelloWorldStubDefault這個(gè)生成的默認(rèn)Stub實(shí)現(xiàn)類上再做一次實(shí)現(xiàn)(繼承并且實(shí)現(xiàn)),例如代碼實(shí)例中的HelloWorldStubImpl類那樣。

三. fdepl

? fdepl文件生成綁定層的代碼,會(huì)生成HelloWorldSomeIPProxyHelloWorldSomeIPStubAdapterInternalHelloWorldSomeIPStubAdapter這幾個(gè)綁定層的類。

3.1 Proxy

? HelloWorldSomeIPProxy類是綁定層生成的Proxy類,其構(gòu)造時(shí)需要傳入綁定層地址(CommonAPI::SomeIP::Address),CommonAPI::SomeIP::Address包含SomeIP服務(wù)實(shí)例的信息:

namespace CommonAPI {
namespace SomeIP {class COMMONAPI_EXPORT Address {...
private:service_id_t service_;     // 服務(wù)IDinstance_id_t instance_;   // 實(shí)例IDmajor_version_t major_version_;   // Max版本號(hào)minor_version_t minor_version_;   // Min版本號(hào)
}
}
}

? 先來(lái)看下創(chuàng)建HelloWorldSomeIPProxy的過(guò)程,首先,用戶需要在自己的應(yīng)用程序中創(chuàng)建核心層的Proxy(HelloWorldProxy)

// HelloWorldClient.cpp
int main() {...// CommonAPI::Address// {// domainid = "local"// interface = HelloWorld::getInterface = "commonapi.HelloWorld:v1_0"// instance = "test"// }std::shared_ptr<HelloWorldProxy<>> myProxy = runtime->buildProxy<HelloWorldProxy>("local", "test");...
}

? 可以看到,創(chuàng)建核心層HelloWorldProxy的時(shí)候,對(duì)應(yīng)的CommonAPI::Address地址已經(jīng)提供出來(lái)了,然后runtime在創(chuàng)建的時(shí)候,會(huì)在調(diào)用核心層的工廠類(CommonAPI::SomeIP::Factory)的createProxy創(chuàng)建綁定層的HelloWorldSomeIPProxy對(duì)象,這個(gè)時(shí)候就需要從AddressTranslator中獲取綁定層地址(SomeipIP的服務(wù)和實(shí)例信息)

// Factory.cppstd::shared_ptr<CommonAPI::Proxy>
Factory::createProxy(const std::string &_domain,const std::string &_interface, const std::string &_instance,const ConnectionId_t &_connectionId) {auto proxyCreateFunctionsIterator= proxyCreateFunctions_.lower_bound(_interface);// 查找是否為該interface注冊(cè)過(guò)SomeIP綁定層的Proxy的創(chuàng)建函數(shù)if (proxyCreateFunctionsIterator!= proxyCreateFunctions_.end()) {   // 找到該CommonAPI interface注冊(cè)的SomeIP綁定層Proxy創(chuàng)建函數(shù)...CommonAPI::Address address(_domain, itsInterface, _instance);Address someipAddress;// 在AddressTranslator中查找CommonAPI地址對(duì)應(yīng)的SomeIP地址if (AddressTranslator::get()->translate(address, someipAddress)) {std::shared_ptr<Connection> itsConnection= getConnection(_connectionId);if (itsConnection) {// 使用注冊(cè)的Proxy創(chuàng)建函數(shù)createHelloWorldSomeIPProxy創(chuàng)建HelloWorldSomeIPProxy// 傳入的CommonAPI::SomeIP::Address為{0x1234, 0x1, 1, 0}std::shared_ptr<Proxy> proxy= proxyCreateFunctionsIterator->second(someipAddress, itsConnection);if (proxy && proxy->init())return proxy;}}}COMMONAPI_ERROR("Creating proxy for \"", _domain, ":", _interface, ":",_instance, "\" failed!");return nullptr;
}

? AddressTranslator中CommonAPI地址和SomeIP綁定層地址的對(duì)應(yīng)關(guān)系在生成的綁定層HelloWorldSomeIPProxy.cpp中插入的:

// HelloWorldSomeIPProxy.cpp
void initializeHelloWorldSomeIPProxy() {// 插入地址對(duì)應(yīng)關(guān)系CommonAPI::SomeIP::AddressTranslator::get()->insert("local:commonapi.HelloWorld:v1_0:test",   // CommonAPI Address0x1234, 0x1, 1, 0);     // CommonAPI::SomeIP Address// 注冊(cè)綁定層SomeIP創(chuàng)建函數(shù)CommonAPI::SomeIP::Factory::get()->registerProxyCreateMethod("commonapi.HelloWorld:v1_0",   // CommonAPI interface&createHelloWorldSomeIPProxy);   // SomeIP Proxy create function
}std::shared_ptr<CommonAPI::SomeIP::Proxy> createHelloWorldSomeIPProxy(const CommonAPI::SomeIP::Address &_address,const std::shared_ptr<CommonAPI::SomeIP::ProxyConnection> &_connection) {return std::make_shared< HelloWorldSomeIPProxy>(_address, _connection);
}

? 然后,生成的綁定層HelloWorldSomeIPProxy也是需要實(shí)現(xiàn)fidl中定義的sayHello接口的,其實(shí)現(xiàn)主要是依賴Deployment類來(lái)包裝輸入的參數(shù),然后通過(guò)ProxyHelper類來(lái)完成參數(shù)的序列化和中間件通信接口的調(diào)用(ProxyHelper::callMethod):

void HelloWorldSomeIPProxy::sayHello(std::string _name, CommonAPI::CallStatus &_internalCallStatus, std::string &_message, const CommonAPI::CallInfo *_info) {CommonAPI::Deployable< std::string, CommonAPI::SomeIP::StringDeployment> deploy_name(_name, static_cast< CommonAPI::SomeIP::StringDeployment* >(nullptr));   // 輸入?yún)?shù)CommonAPI::Deployable< std::string, CommonAPI::SomeIP::StringDeployment> deploy_message(static_cast< CommonAPI::SomeIP::StringDeployment* >(nullptr));   // 返回參數(shù)// 依賴ProxyHelper類發(fā)起someip的Method請(qǐng)求(REQUEST-RESPONSE)CommonAPI::SomeIP::ProxyHelper<...>::callMethodWithReply(    // ProxyHelper類是個(gè)靜態(tài)類,內(nèi)部都是靜態(tài)方法,不保存成員*this,    // 主要是提供HelloWorldSomeIPProxy內(nèi)部的Connection指針CommonAPI::SomeIP::method_id_t(0x7b),false,false,(_info ? _info : &CommonAPI::SomeIP::defaultCallInfo),deploy_name,_internalCallStatus,deploy_message);_message = deploy_message.getValue();
}

? 而ProxyHelper的callMethod函數(shù)則依賴Connetion類來(lái)完成中間件接口的調(diào)用。

template <typename Proxy_ = Proxy>
static void callMethod(...) {if (_proxy.isAvailable()) {  // 對(duì)端service為可用狀態(tài)// 首先序列化參數(shù)OutputStream outputStream(_methodCall, _isLittleEndian);const bool success = SerializableArguments<InArgs_...>::serialize(outputStream, _inArgs...);...// 通過(guò)Connection指針調(diào)用到vsomeip中間件接口bool success = _proxy.getConnection()->sendMessage(_methodCall);  ...} else {...}
}

3.2 Stub

? HelloWorldSomeIPStubAdapterInternalHelloWorldSomeIPStubAdapter的父類,此外,HelloWorldSomeIPStubAdapterInternal類也是綁定層對(duì)于核心層HelloWorldStubAdapter接口類的實(shí)現(xiàn)。

? 總體來(lái)說(shuō),StubAdapter類是在Stub和中間件之間做適配功能的類,并且實(shí)現(xiàn)了核心層的StubAdapter接口類中定義的接口。

? 先看下HelloWorldSomeIPStubAdapterInternal類,HelloWorldSomeIPStubAdapterInternal繼承自核心層生成的HelloWorldStubAdapter接口和CommonAPI::SomeIP::StubAdapterHelper類。

? HelloWorldSomeIPStubAdapterInternal類有獲取內(nèi)部屬性的成員,其中包括Version信息的屬性的getHelloWorldInterfaceVersionStubDispatcher成員,如果fidl中定義了業(yè)務(wù)的屬性,則還會(huì)包含該業(yè)務(wù)屬性的StubDispatcher成員,例如https://github.com/COVESA/capicxx-core-tools/tree/master/CommonAPI-Examples/E02Attributes 中fdepl生成的E02AttributesSomeIPStubAdapter.hpp文件中,E02AttributesSomeIPStubAdapterInternal類就有g(shù)etXAttributeStubDispatcher,getA1AttributeStubDispatcher和getE02AttributesInterfaceVersionStubDispatcher,其中g(shù)etXAttributeStubDispatcher對(duì)應(yīng)fidl中定義的屬性x,getA1AttributeStubDispatcher對(duì)應(yīng)fidl中定義的屬性a1。

? SomeIPStubAdapterInternal類內(nèi)部的StubDispatcher成員都是GetAttributeStubDispatcher類型的,實(shí)現(xiàn)了StubDispatcher接口,查看GetAttributeStubDispatcher類的實(shí)現(xiàn)可以看到內(nèi)部成員函數(shù)dispatchMessage,這個(gè)函數(shù)就是通過(guò)Connection類調(diào)用SomeIP中間件將屬性值通過(guò)消息的方式發(fā)送給客戶端:

template <typename StubClass_, typename AttributeType_, typename AttributeDepl_ = EmptyDeployment>
class GetAttributeStubDispatcher: public StubDispatcher<StubClass_> {
public:...bool dispatchMessage(const Message &message, const std::shared_ptr<StubClass_> &stub,RemoteEventHandlerType* _remoteEventHandler,std::shared_ptr<ProxyConnection> _connection) {...return sendAttributeValueReply(message, stub, _connection);}protected:   inline bool sendAttributeValueReply(const Message &message, const std::shared_ptr<StubClass_>& stub,std::shared_ptr<ProxyConnection> _connection) {...return _connection->sendMessage(reply);}...}

? 當(dāng)服務(wù)端進(jìn)程收到客戶端發(fā)送的對(duì)屬性訪問(wèn)的SOMEIP method消息觸發(fā)該接口的調(diào)用,調(diào)用棧如下:

Connection::handleStubReceive   // 從中間件收到client發(fā)送的消息// 處理消息(根據(jù)消息中的serviceID, instanceID找到對(duì)應(yīng)的CommonAPI::SomeIP::StubAdapter// 例如E02AttributesSomeIPStubAdapterInternal,HelloWorldSomeIPStubAdapterInternal StubManager::handleMessage StubAdapterHelper::onInterfaceMessage  // StubAdapterHelper也是E02AttributesSomeIPStubAdapterInternal的父類StubAdapterHelper::findDispatcherAndHandleStubDispatcher::dispatchMessage  // 內(nèi)部調(diào)用Stub對(duì)應(yīng)的get屬性值的方法獲取當(dāng)前屬性值

? 當(dāng)服務(wù)端進(jìn)程將屬性的值通過(guò)SOMEIP消息回復(fù)給客戶端的時(shí)候,首先是需要知道當(dāng)前服務(wù)instance中該屬性的值對(duì)不對(duì),fidl文件生成的核心層Stub中提供這個(gè)屬性的值的獲取方法:

// src-gen/v1/commonapi/examples/E02AttributesStubDefault.hpp
COMMONAPI_EXPORT virtual const int32_t &getXAttribute() {return xAttributeValue_;
}

? 也就是說(shuō)如果有Stub對(duì)象,就可以調(diào)用其getXAttribute方法獲取其x屬性的當(dāng)前值,然后在E02AttributesSomeIPStubAdapterInternal的構(gòu)造函數(shù)中可以看到,HelloWorldSomeIPStubAdapterInternal構(gòu)造函數(shù)中創(chuàng)建x屬性對(duì)應(yīng)的getXAttributeStubDispatcher對(duì)象時(shí)提供getXAttribute方法:

E02AttributesSomeIPStubAdapterInternal(...getXAttributeStubDispatcher(&::v1::commonapi::examples::E02AttributesStub::lockXAttribute,&::v1::commonapi::examples::E02AttributesStub::getXAttribute,  // 注冊(cè)到內(nèi)部getStubFunctor_成員中false,_stub->hasElement(0)),22...
}

? getXAttributeStubDispatcher是GetAttributeStubDispatcher類型的,其dispatchMessage方法中可以看到對(duì)get屬性值方法的調(diào)用:

class GetAttributeStubDispatcher: public StubDispatcher<StubClass_> {
public:...bool dispatchMessage(const Message &message, const std::shared_ptr<StubClass_> &stub,...return sendAttributeValueReply(message, stub, _connection);}
protected:inline bool sendAttributeValueReply(const Message &message, const std::shared_ptr<StubClass_>& stub,std::shared_ptr<ProxyConnection> _connection) {Message reply = message.createResponseMessage();OutputStream outputStream(reply, isLittleEndian_);...// 獲取屬性值auto deployable = CommonAPI::Deployable<AttributeType_, AttributeDepl_>((stub.get()->*getStubFunctor_)(clientId), depl_);outputStream << deployable;  // 寫入消息outputStream.flush();return _connection->sendMessage(reply);  // 發(fā)送屬性值get-method消息的回復(fù)消息}
}

HelloWorldSomeIPStubAdapter繼承了HelloWorldSomeIPStubAdapterInternal,也就具備了通過(guò)綁定層調(diào)用SomeIP中間件進(jìn)行通信的功能,在此基礎(chǔ)上,主要增加了一個(gè)功能,就是在構(gòu)造函數(shù)中增加了SomeIP地址和Connection對(duì)象的傳入,有了這兩個(gè)對(duì)象,HelloWorldSomeIPStubAdapterInternal的SomeIP通信功能才能真正工作起來(lái)。

public:HelloWorldSomeIPStubAdapter(const CommonAPI::SomeIP::Address &_address,const std::shared_ptr<CommonAPI::SomeIP::ProxyConnection> &_connection,const std::shared_ptr<CommonAPI::StubBase> &_stub): CommonAPI::SomeIP::StubAdapter(_address, _connection),HelloWorldSomeIPStubAdapterInternal<_Stub, _Stubs...>(_address, _connection, _stub) {}

? 那么這個(gè)構(gòu)造函數(shù)什么時(shí)候調(diào)用的呢?是CommonAPI::SomeIP::Factory調(diào)用的,之前在核心層說(shuō)過(guò),生成的綁定層Stub代碼會(huì)將HelloWorldSomeIPStubAdapter的創(chuàng)建函數(shù)和對(duì)應(yīng)的CommonAPI::Address注冊(cè)給Factory:

void initializeHelloWorldSomeIPStubAdapter() {CommonAPI::SomeIP::AddressTranslator::get()->insert("local:commonapi.HelloWorld:v1_0:test",0x1234, 0x1, 1, 0);CommonAPI::SomeIP::Factory::get()->registerStubAdapterCreateMethod(   // 注冊(cè)HelloWorldSomeIPStubAdapter的創(chuàng)建函數(shù)"commonapi.HelloWorld:v1_0",&createHelloWorldSomeIPStubAdapter);
}

? 當(dāng)我們?cè)诜?wù)端代碼中注冊(cè)我們的HelloWorldStubImpl時(shí),通過(guò)核心層調(diào)用到綁定層的SomeIP::Factory進(jìn)行HelloWorldSomeIPStubAdapter對(duì)象的創(chuàng)建:

int main() {std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::get();std::shared_ptr<HelloWorldStubImpl> myService =std::make_shared<HelloWorldStubImpl>();runtime->registerService("local", "test", myService);   // 這一步會(huì)調(diào)用到SomeIP::Factory創(chuàng)建HelloWorldSomeIPStubAdapter...
}
http://www.risenshineclean.com/news/7542.html

相關(guān)文章:

  • 做網(wǎng)站webform mvc百度競(jìng)價(jià)怎么做效果好
  • 小學(xué)網(wǎng)站建設(shè)及使用收錄
  • 網(wǎng)站建設(shè)建設(shè)公司有哪些如何建立電商平臺(tái)
  • 政府網(wǎng)站建設(shè)的創(chuàng)新機(jī)制百度網(wǎng)游排行榜
  • 公眾號(hào)模板免費(fèi)關(guān)鍵詞優(yōu)化技巧
  • 哪些網(wǎng)站屬于b2b模式電子商務(wù)推廣
  • 社保網(wǎng)站是每月1-6號(hào)都是在建設(shè)中的嗎發(fā)外鏈軟件
  • 國(guó)內(nèi)外優(yōu)秀建筑設(shè)計(jì)網(wǎng)站濟(jì)南優(yōu)化網(wǎng)站的哪家好
  • 提供深圳網(wǎng)站制作公司廣告搜索引擎
  • 創(chuàng)意福州網(wǎng)站建設(shè)appstore關(guān)鍵詞優(yōu)化
  • 做網(wǎng)站需要找人優(yōu)化嗎百度app下載安裝官方免費(fèi)下載
  • 網(wǎng)站制作什么樣的字體好看什么是seo推廣
  • 讓其他公司做網(wǎng)站應(yīng)注意什么問(wèn)題桂林seo排名
  • 吉林省建筑市場(chǎng)監(jiān)管公共服務(wù)平臺(tái)朝陽(yáng)seo
  • 外國(guó)排版網(wǎng)站網(wǎng)絡(luò)營(yíng)銷什么意思
  • 網(wǎng)站建設(shè)鏈接演示湖北百度推廣電話
  • 南寧網(wǎng)站建設(shè)seo友鏈交換網(wǎng)站源碼
  • 做模具做什么網(wǎng)站信息流廣告案例
  • 西寧網(wǎng)站建設(shè)公司排行株洲seo快速排名
  • 校園網(wǎng)站群建設(shè)搜索引擎優(yōu)化入門
  • 生日禮物自己做網(wǎng)站南昌seo優(yōu)化公司
  • 周口哪家做網(wǎng)站好湖南平臺(tái)網(wǎng)站建設(shè)制作
  • 網(wǎng)站開發(fā)術(shù)語(yǔ)長(zhǎng)沙網(wǎng)站推廣智投未來(lái)
  • 潮州市建設(shè)局官方網(wǎng)站下拉詞排名
  • wordpress置頂文章全文顯示seo怎樣
  • 做快消品看那些網(wǎng)站好外貿(mào)網(wǎng)站平臺(tái)都有哪些
  • 自建網(wǎng)站模板營(yíng)銷外包
  • 網(wǎng)站建設(shè)網(wǎng)站建設(shè)網(wǎng)站運(yùn)營(yíng)與維護(hù)
  • 現(xiàn)在在市場(chǎng)上做網(wǎng)站怎么樣哪個(gè)平臺(tái)做推廣效果好
  • 網(wǎng)站到期怎么續(xù)費(fèi)網(wǎng)上商城推廣13種方法