成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

源碼分析—解析Proxy - Stub 架構的奧秘

系統 OpenHarmony
binder驅動通過mmap將內核態代碼映射到用戶態,直接讀寫數據這樣就完成了跨進程的調用。不過這不是該篇內容的重點,本片主要講一下proxy - stub 的設計模式。

??想了解更多內容,請訪問:??

??51CTO和華為官方合作共建的鴻蒙技術社區??

??https://ost.51cto.com??

服務概覽

openHarmony 中存在很多的服務,一般來說可以使得A應用調用B服務的方法,就像在自己進程中調用一樣,這里具體的實現實際通過binder驅動實現。binder驅動通過mmap將內核態代碼映射到用戶態,直接讀寫數據這樣就完成了跨進程的調用。不過這不是該篇內容的重點,本片主要講一下proxy - stub 的設計模式。

服務的一般編碼模式

使用proxy - stub 架構編程,大致可以分為以下三個步驟:

  1. 設計接口類繼承 IRemoteBroker,接口方法一般設計為虛方法。
  2. 設計proxy類 繼承至 IRemoteProxy,并且實現sendRequest方法和自身虛方法。
  3. 設計stub類 繼承至 IRemoteStub ,并且實現OnRemote方法和自身虛方法。

這樣我們就可以在調用是調用proxy類的接口方法就像調用stub類的接口方法一樣了。

源碼剖析

我們通過閱讀源碼,解開其神秘的面紗。我們現在關注幾個重點的類。

IRemoteObject:

class IRemoteObject : public virtual Parcelable, public virtual RefBase {
public:
enum {
IF_PROT_DEFAULT, /* Invoker family. */
IF_PROT_BINDER = IF_PROT_DEFAULT,
IF_PROT_DATABUS,
};
enum {
DATABUS_TYPE,
};
class DeathRecipient : public RefBase {
public:
enum {
ADD_DEATH_RECIPIENT,
REMOVE_DEATH_RECIPIENT,
NOTICE_DEATH_RECIPIENT,
TEST_SERVICE_DEATH_RECIPIENT,
TEST_DEVICE_DEATH_RECIPIENT,
};
virtual void OnRemoteDied(const wptr<IRemoteObject> &object) = 0;
};
virtual int32_t GetObjectRefCount() = 0;
virtual int SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) = 0;
virtual bool IsProxyObject() const;
virtual bool CheckObjectLegality() const;
virtual bool AddDeathRecipient(const sptr<DeathRecipient> &recipient) = 0;
virtual bool RemoveDeathRecipient(const sptr<DeathRecipient> &recipient) = 0;
virtual bool Marshalling(Parcel &parcel) const override;
static IRemoteObject *Unmarshalling(Parcel &parcel);
static bool Marshalling(Parcel &parcel, const sptr<IRemoteObject> &object);
virtual sptr<IRemoteBroker> AsInterface();
virtual int Dump(int fd, const std::vector<std::u16string> &args) = 0;
const std::u16string descriptor_;
std::u16string GetObjectDescriptor() const;
protected:
explicit IRemoteObject(std::u16string descriptor = nullptr);
};

這就是真正在binder驅動中數據傳輸的類,繼承自 Parcelable 。而繼承RefBase 可以理解為智能指針的控制塊。openharmony中這里并沒有直接使用c++標準庫中的智能指針,而是使用 sptr 和refbase兩個類共同構建,也就是裸指針和控制塊相關信息。使用后者的方式,更加解耦。符合復雜架構設計理念。

IRemoteBroker:

class IRemoteBroker : public virtual RefBase {
public:
IRemoteBroker() = default;
virtual ~IRemoteBroker() override = default;
virtual sptr<IRemoteObject> AsObject() = 0;
static inline sptr<IRemoteBroker> AsImplement(const sptr<IRemoteObject> &object)
{
return nullptr;
}
};
#define DECLARE_INTERFACE_DESCRIPTOR(DESCRIPTOR) \
static inline const std::u16string metaDescriptor_ = { DESCRIPTOR }; \
static inline const std::u16string &GetDescriptor() \
{ \
return metaDescriptor_; \
}

一般的接口類,通過metaDescriptor_ 作為表示區分標識。

IRemoteProxy:

namespace OHOS {
template <typename INTERFACE> class IRemoteProxy : public PeerHolder, public INTERFACE {
public:
explicit IRemoteProxy(const sptr<IRemoteObject> &object);
~IRemoteProxy() override = default;
protected:
sptr<IRemoteObject> AsObject() override;
};
template <typename INTERFACE>
IRemoteProxy<INTERFACE>::IRemoteProxy(const sptr<IRemoteObject> &object) : PeerHolder(object)
{
}
template <typename INTERFACE> sptr<IRemoteObject> IRemoteProxy<INTERFACE>::AsObject()
{
return Remote();
}
} // namespace OHOS

IRemoteProxy 使用c++的crtp (奇特重現模板模式)編程,使得父類可以調用子類的方法。繼承自peerhold (其實就是包括一個IRemoteObject對象) 。

IRemoteStub:

namespace OHOS {
template <typename INTERFACE> class IRemoteStub : public IPCObjectStub, public INTERFACE {
public:
IRemoteStub();
virtual ~IRemoteStub() = default;
sptr<IRemoteObject> AsObject() override;
sptr<IRemoteBroker> AsInterface() override;
};
template <typename INTERFACE> IRemoteStub<INTERFACE>::IRemoteStub() : IPCObjectStub(INTERFACE::GetDescriptor()) {}

template <typename INTERFACE> sptr<IRemoteBroker> IRemoteStub<INTERFACE>::AsInterface()
{
return this;
}
template <typename INTERFACE> sptr<IRemoteObject> IRemoteStub<INTERFACE>::AsObject()
{
return this;
}
} // namespace OHOS

stub對象較于proxy對象復雜一些,也使用crtp編程。會繼承IPCObjectStub (也是iremoteObject對象)。

看到這里,可能有人疑惑,為什么proxy調用,會直接調用到stub這端呢?其實奧秘就在于stub 繼承的IPCObjectStub (繼承iremoteObject) 對象,就是這個iremoteObject對象。proxy的構造繼承 peerhold ,peerhold 類中的iremoteObject 對象和 IPCObjectStub 這個是什么關系呢?其實peerhold是IPCObjectStub 的引用對象,實際類型是 IPCObjectProxy 。這兩者在ipc框架中,IPCObjectProxy 實際使用sendrequest ,IPCObjectStub便會調用OnremoteRequest。如果有興趣,我們下次可以分析IPC框架具體是如何實現的。

??想了解更多內容,請訪問:??

??51CTO和華為官方合作共建的鴻蒙技術社區??

??https://ost.51cto.com??

責任編輯:jianghua 來源: 鴻蒙社區
相關推薦

2018-06-20 11:41:06

企業架構

2011-04-13 13:14:41

EIGRP STUB

2024-12-24 09:17:31

2022-06-07 10:33:29

Camera組件鴻蒙

2025-03-05 09:30:00

MySQL流式查詢數據庫

2009-09-09 15:43:15

2010-08-13 10:56:53

2025-02-10 10:59:52

2024-12-27 09:32:25

MyBatis代碼

2018-07-19 15:57:46

ViewStub源碼方法

2014-08-19 10:30:30

Swift源碼OpenStack架構

2016-11-25 13:14:50

Flume架構源碼

2010-02-04 11:06:14

2010-03-24 17:03:57

Python源碼分析

2011-04-29 13:40:37

MongoDBCommand

2024-04-08 07:58:11

Python數據類型字符串

2024-08-26 10:31:23

2023-03-17 07:53:20

K8sAPIServerKubernetes

2016-11-25 13:26:50

Flume架構源碼

2016-11-29 09:38:06

Flume架構核心組件
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲精品一区二区在线观看 | 一区二区国产精品 | 中文字幕91av | 中文字幕精品一区二区三区精品 | 韩国av一区二区 | 欧美激情国产日韩精品一区18 | 国产精品69毛片高清亚洲 | 人人做人人澡人人爽欧美 | 国产成人av免费看 | 欧美性吧 | 国产在线观看一区二区三区 | 免费99视频 | 国产精品99久久久久久动医院 | 天天噜天天干 | 欧美精品1区 | 中文字幕一区在线观看视频 | 亚洲三级在线观看 | 少妇一级淫片免费放播放 | 久久激情视频 | 我想看国产一级毛片 | 日韩成人在线免费观看 | 国产成人免费在线 | 天天拍天天插 | 青青久草 | 亚洲精品久久久久久久久久吃药 | 99久久精品国产麻豆演员表 | 欧美精品一区二区在线观看 | 99精品国产一区二区三区 | www.国产日本| 天天操天天摸天天爽 | 欧美成人精品一区二区三区 | 久久久精品| 欧美性乱| 亚洲成人精品 | 欧美日韩国产中文字幕 | 久久精品国产一区二区三区 | 欧洲一级视频 | 国产视频久久 | 欧美一区日韩一区 | 武道仙尊动漫在线观看 | 欧美一区视频 |