#java #c #idl #data-distribution-service #opendds
#java #c #idl #служба распространения данных #opendds
Вопрос:
Я использую IDL для определения данных для приложения с использованием OpenDDS.
Я также хочу использовать IDL для определения интерфейсов для приложения, но OpenDDS (и, похоже, большинство других реализаций DDS) не поддерживают интерфейсы в IDL.
Существуют ли какие-либо компиляторы, которые будут генерировать простые заглушки из интерфейсов IDL? Мне нужно, чтобы он поддерживал хотя бы C и Java.
Все компиляторы IDL, входящие в состав CORBA ORBs, генерируют много специфичного для CORBA кода и шаблонов. Я хочу что-то, что выполняет простое сопоставление с IDL на C / Java / etc. Например, если у меня есть этот IDL:
module sample_module {
interface sample_interface {
attribute char sample_field;
boolean sample_func();
};
};
Я хочу, чтобы компилятор генерировал подобные файлы на C :
namespace sample_module {
class sample_interface {
char sample_field;
boolean sample_func();
};
};
Ответ №1:
Вы могли бы использовать local interface
поддержку, которая приводит к базовому классу C с чисто виртуальными методами для реализации. Это, например, используется LwCCM для определения компонентов, см., Например, AXCIOMA, там мы используем локальные интерфейсы в сочетании с данными, определенными в IDL. Смотрите одну из наших статей для получения дополнительной информации.
В качестве альтернативы вы также можете создать свою собственную пользовательскую генерацию на основе IDL, в TAOX11 / AXCIOMA / R2CORBA мы используем RIDL, вы можете создать пользовательский сервер для генерации некоторого кода, специфичного для интерфейсов
Комментарии:
1. Я думаю, что это единственное реальное решение. Я собираюсь попробовать написать бэкэнд для omniidl , потому что я лучше знаком с python.
2. Поддержка интерфейсов DDS определена в стандарте RPC поверх DDS. Более подробная информация в моем ответе.
Ответ №2:
Вне интерфейсов в IDL спецификаций DDS, сам DDS, насколько я знаю, не используется для интерфейсов. Он всегда ограничивает свой собственный IDL подмножеством CORBA. Из-за этого OpenDDS не поддерживает пользовательские интерфейсы за пределами поддержки, которая уже поставляется с using tao_idl
. Необязательное отображение C 11, которое может быть сгенерировано, opendds_idl
свободно от всех шаблонов CORBA, как вы хотите, но на данный момент оно не поддерживает интерфейсы. Я думаю, что отображение Java поддерживает их только для конкретной ситуации на основе OpenDDS на основе JNI. Даже при использовании сопоставления TAO с C OpenDDS не поддерживает использование interface
типов в качестве типа темы DDS или внутри него.
Я не могу говорить так много о других реализациях DDS, как о OpenDDS, но я знаю, что на этой странице поддержки Connext говорится, что они также не поддерживают интерфейсы. В нем говорится, что они поддерживают valuetype
, что-то вроде an interface
, но они рассматривают его как a struct
и игнорируют операции над ними.
Комментарии:
1. Это был вывод, к которому я тоже пришел. Я просто надеялся, что кто-то с большим опытом работы с IDL и DDS будет знать то, чего я не знал.
2. Поддержка интерфейсов DDS определена в стандарте RPC поверх стандарта DDS. Более подробная информация в моем ответе.
Ответ №3:
Существует стандарт OMG, называемый удаленным вызовом процедур через DDS (RPC через DDS), который определяет, как интерфейсы IDL могут быть сопоставлены с кодом (он входит в семейство стандартов DDS). CoreDX DDS поддерживает этот стандарт для нескольких целевых языков (включая C , Java и C #).
В дополнение к простому отображению интерфейса на целевой язык, стандарт RPC over DDS предоставляет способ использования DDS в качестве базового транспорта для операций RPC. Он обеспечивает как низкоуровневое взаимодействие (то есть обработку отправки и получения запросов вручную), так и высокоуровневое (вызов метода «интерфейс») API-интерфейсы. В любом случае межпроцессное взаимодействие осуществляется через DDS таким образом, чтобы оно было совместимым. На мой взгляд, это очень мощный подход.
Вот несколько примеров IDL:
module robot {
exception TooFast {};
enum Command { START_COMMAND, STOP_COMMAND, TERMINATE_COMMAND };
struct Status
{
string msg;
};
@DDSService
interface RobotControl
{
void command(Command com);
float setSpeed(float speed) raises (TooFast);
float getSpeed();
void getStatus(out Status status);
};
};
ПРИМЕЧАНИЕ: Аннотация «@DDSService» информирует компилятор IDL о необходимости генерировать RPC через поддержку DDS для интерфейса.
Без аннотации @DDSService наш генератор кода просто сгенерирует объявление класса [которое, я думаю, вы ищете], которое выглядит примерно так:
class RobotControl {
public:
RobotControl();
~RobotControl();
public:
virtual void command (
/* IN */ const enum robot::Command com ) = 0;
virtual float setSpeed (
/* IN */ const float speed ) = 0;
virtual float getSpeed ( ) = 0;
virtual void getStatus (
/* OUT */ struct robot::Status amp; status ) = 0;
};
С аннотацией @DDSService генерируется намного больше кода, который обеспечивает полную реализацию на стороне клиента (robot.RobotControlClient) и абстрактная серверная часть, готовая к реализации (robot.RobotControlService). При этом ваше клиентское приложение может просто сделать это:
RobotControlClient robotClient = new RobotControlClient( client_params );
robotClient.setSped( 10 );
Серверное приложение может расширять робота.RobotControlService и реализуйте вызовы служб, что-то вроде этого:
public class MyRobotControlService extends RobotControlService {
....
private static final float MAX_SPEED = (float)20.0;
public float
setSpeed ( /* in */ float speed ) throws TooFast
{
float retval = (float)0.0;
if (speed < MAX_SPEED)
{
current_speed = speed;
retval = this.current_speed;
}
else
{
/* EXCEPTION: */
throw new robot.TooFast();
/* not reached... */
}
return retval;
}