この節では SDO サービスのプロバイダの実装方法について説明します。
SDO サービスプロバイダは、自らサービスを外部のツールやアプリケーション・RTC などに対して提供する主体となります。
前述のとおり、SDO サービスプロバイダのオブジェクトは通常、共有オブジェクト (so、DLL) としてコンパイル・リンクされます。 このオブジェクトが RTC のプロセスにロードされ動作する実際のライフサイクルは以下の通りとなります。
[RTC] [SDO service] [Other] | : | | instantiate : | |------------->: | | init() | | |------------->| | | | get_service_profiles() | |<--------------------------------------| | | get_sdo_service() | |<--------------------------------------| | | use service | | |<-----------------------| | | | | finalize() | | |------------->x | x x |
SDO サービスプロバイダを実装する際には、SdoServiceProviderBase 基底クラスおよび、CORBA サーバントスケルトンクラスを継承した一つのクラスを作成します。
#include <rtm/SdoServiceProviderBase.h> class MySdoServiceConsumer : SdoServiceProviderBase, {
このクラスの実装に当たっては、少なくとも以下の純粋仮想関数および、グローバルなモジュール初期化関数を実装する必要があります。
以下に、各関数の詳細な振る舞いを示す。
関数プロトタイプ bool init(RTObject_impl& rtobj, const SDOPackage::ServiceProfile& profile)
初期化関数。与えられた RTObject および ServiceProfile から、当該オブジェクトを初期化します。このサービスが sdo.service.provider.enabled_services で有効化されていれば、この関数は対応するRTCがインスタンス化された直後に呼び出されます。
ServiceProfile には以下の情報が入った状態で呼び出されます。
ServiceProfile.id | 当該サービスのIFR型 |
ServiceProfile.interface_type | 当該サービスのIFR型 |
ServiceProfile.service | 当該サービスのオブジェクト参照 |
ServiceProfile.properties | rtc.conf や <component>.conf 等で与えられた SDOサービス固有のオプションが渡される。confファイル内では、<pragma>.<module_name>.<interface_name> というプリフィックスをつけたオプションとして与えることができ、properties 内には、このプリフィックスを除いたオプションが key:value 形式で含まれている。 |
関数内では、主に properties から設定内容を読み込みサービス固有の設定等を行います。与えられた ServiceProfileの内容が不正、あるいはその他の理由で当該サービスをインスタンス化しない場合は false を返します。その場合、finalize() が呼び出されその後オブジェクトは削除されます。それ以外の場合は true を返すと、サービスオブジェクトは RTC 内に保持されます。
関数プロトタイプ bool reinit(const SDOPackage::ServiceProfile& profile)
再初期化関数。ServiceProfile は設定情報更新のため同一IDで呼び出されることが有りますが、その際にこの関数が新たな ServiceProfile とともに呼び出されます。関数内では、設定の変更など再初期化処理を実装します。
関数プロトタイプ const SDOPackage::ServiceProfile& getProfile() const
設定されたプロファイルを返す関数です。
関数プロトタイプ const SDOPackage::ServiceProfile& getProfile() const
終了処理。RTCオブジェクトが解体されるか、init()処理においてfalseが返された場合は、この関数が呼び出されたのちオブジェクトは解体されます。関数内では終了処理を実装します。
関数プロトタイプ DLL_EXPORT void ComponentObserverProviderInit()
この関数は共有オブジェクト (.so や .dll) のエントリポイントとなります。この関数内では、RTC::SdoServiceProviderFactory に対して、当該 SDOプロバイダオブジェクトのインターフェースIDおよび生成(Creator)・破壊(Desctuctor)・関数(ファンクタ)を登録します。
以下は、典型的な Init() 関数の実装例です。
extern "C" { void MySdoServiceProviderInit() { RTC::SdoServiceProviderFactory& factory = RTC::SdoServiceProviderFactory::instance(); factory.addFactory(CORBA_Util::toRepositoryId<OpenRTM::MySdoService>(), ::coil::Creator< ::RTC::SdoServiceProviderBase, ::RTC::MySdoServiceProvider>, ::coil::Destructor< ::RTC::SdoServiceProviderBase, ::RTC::MySdoServiceProvider>); } };
SdoServiceProvider は通常共有オブジェクトとしてコンパイル・リンクされます。
共有オブジェクトのエントリポイントは通常コンパイルされたファイル名の basename + "Init" となります。(別の名称の場合、rtc.confのオプションで別途指定する必要があります。)
以下に、クラス名、ファイル名、エントリポイント関数名の推奨例を示します。