При сборке решения компилятор 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;
};