При сборке решения компилятор NK на основе edl-, cdl- и idl-описаний генерирует набор специальных методов и типов, упрощающих формирование, отправку, прием и обработку IPC-сообщений.
Рассмотрим статическое описание сущности server
из примера echo. Это описание состоит из трех файлов: server.edl
, ping.cdl
и ping.idl
:
server.edl
/* Описание сущности server. */
entity server
/* ping_comp - именованный экземпляр компонента ping. */
ping_comp: ping
ping.cdl
/* Описание компонента ping. */
component ping
/* ping_impl - реализация интерфейса IPing, объявленного в пакете ping. */
ping_impl: ping.IPing
ping.idl
/* Описание пакета ping. */
package ping
interface IPing {
Ping(in UInt32 value, out UInt32 result);
}
На основе этих файлов будут сгенерированы файлы server.edl.h
, server.edl.c
, ping.cdl.h
, ping.cdl.c
, ping.idl.h
и ping.idl.c
, содержащие следующие методы и типы:
Методы и типы, общие для клиента и сервера
В нашем примере будет сгенерирован один абстрактный интерфейс – IPing
:
struct IPing_ops {
nk_err_t (*Ping)(struct IPing *,
const struct IPing_req *,
const struct nk_arena *,
struct IPing_res *,
struct nk_arena *); };
struct IPing {
const struct IPing_ops *ops;
};
При вызове интерфейсного метода в запросе автоматически проставляются соответствующие значения RIID и MID, после чего вызывается функция nk_transport_call()
.
В нашем примере будет сгенерирован единственный интерфейсный метод IPing_Ping
:
nk_err_t IPing_Ping(struct IPing *,
const struct IPing_Ping_req *,
const struct nk_arena *,
struct IPing_Ping_res *,
struct nk_arena *);
Методы и типы, используемые только на клиенте
Прокси-объект используется как аргумент интерфейсного метода. В нашем примере будет сгенерирован единственный тип прокси-объекта IPing_proxy
:
struct IPing_proxy {
struct IPing base;
struct nk_transport *transport;
nk_iid_t iid;
};
В нашем примере будет сгенерирована единственная инициализирующая функция IPing_proxy_init
:
void IPing_proxy_init(struct IPing_proxy *, struct nk_transport *, nk_iid_t);
В нашем примере будет сгенерировано два таких типа: IPing_Ping_req
(для запроса) и IPing_Ping_res
(для ответа).
struct IPing_Ping_req {
struct nk_message base_;
nk_uint32_t value;
};
struct IPing_Ping_res {
struct nk_message base_;
nk_uint32_t result;
};
Методы и типы, используемые только на сервере
В нашем примере будет сгенерирована структура ping_component
и функция ping_component_init
:
struct ping_component {
struct IPing *ping_impl;
};
void ping_component_init(struct ping_component *, struct IPing *);
В нашем примере будет сгенерирована структура server_entity
и функция server_entity_init
:
struct server_entity {
struct ping_component *ping_comp;
};
void server_entity_init(struct server_entity *, struct ping_component *);
Диспетчер анализирует значения RIID и MID, содержащиеся в запросе, и вызывает реализацию соответствующего метода.
Если сообщение не соответствует интерфейсу (например, оно для другого интерфейса или компонента), диспетчер возвращает NK_EOK
или NK_ENOENT
.
В нашем примере будет сгенерировано три диспетчера – IPing_dispatch
, ping_component_dispatch
и server_entity_dispatch
:
nk_err_t IPing_dispatch(struct IPing *,
const struct nk_message *,
const struct nk_arena *,
struct nk_message *,
struct nk_arena *);
nk_err_t ping_component_dispatch(struct ping_component *,
const struct nk_message *,
const struct nk_arena *,
struct nk_message *,
struct nk_arena *);
nk_err_t server_entity_dispatch(struct server_entity *,
const struct nk_message *,
const struct nk_arena *,
struct nk_message *,
struct nk_arena *);
В нашем примере будет сгенерировано два таких типа: IPing_req
(для запроса) и IPing_res
(для ответа).
union IPing_req {
struct nk_message base_;
struct IPing_Ping_req Ping;
};
union IPing_res {
struct nk_message base_;
struct IPing_Ping_res Ping;
};
В нашем примере будет сгенерировано два таких типа: ping_component_req
(для запроса) и ping_component_res
(для ответа).
union ping_component_req {
struct nk_message base_;
union IPing_req ping_impl;
};
union ping_component_res {
struct nk_message base_;
union IPing_res ping_impl;
};
В нашем примере будет сгенерировано два таких типа: server_entity_req
(для запроса) и server_entity_res
(для ответа).
union server_entity_req {
struct nk_message base_;
union IPing_req ping_comp_ping_impl;
};
union server_entity_res {
struct nk_message base_;
union IPing_res ping_comp_ping_impl;
};