torutkのブログ

ソフトウェア・エンジニアのブログ

ACE+TAO

年内に予定されている次のリリース(1.6.2)において、Visual Studio 2008がサポートされる予定。

ACE_InputCDR, ACE_OutputCDRクラスの調査

2008.1.13修正
ACEでソケット通信は簡単に記述できるようになりますが(特にUDPは!)、異なるエンディアンのプラットフォーム間ではエンディアン変換が面倒です。(例、Intel x86 CPUと、PowerPC CPUとの間の通信)
エンディアン変換を作りこむ際に、CORBA共通データ表現形式(CDR)を使ってデータを送受するとエンディアン変換が楽になります。

CDRのポリシーは、バイト順序については送り手がバイト順序の情報を添えてデータを送信し、受け手がデータ内のバイト順序の情報を見て必要な倍と順序の変換を行うというものです。

#include <ace/CDR_Stream.h>
    // marshal
    char code = 'z';
    int range = 254;
    ACE_OutputCDR output;
    output << ACE_OutputCDR::from_boolean(ACE_CDR_BYTE_ORDER);
    output << ACE_CDR::Char(code);
    output << ACE_CDR::Long(range);
    size_t length = output.length();
    const char* buffer = output.buffer();

    // unmarshal
    ACE_InputCDR input(buffer, length);
    ACE_CDR::Boolean byteOrder;
    ACE_CDR::Char myCode;
    ACE_CDR::Long myRange;
    input >> ACE_InputCDR::to_boolean(byteOrder);
    input.reset_byte_order(byteOrder);
    input >> myCode;
    input >> myRange;

データの送信側は、まずバイト順序の情報をACEライブラリの定義(ACE_CDR_BYTE_ORDER)から取得しCDRに入れます。それから送信したいデータをCDRに入れていきます。CDRに入れるデータはACE_CDRに定義されている各型(CORBAの型情報と同じ)なので、通常C++で使用する型からCDR型に変換して入れています。

データの受信側は、まずバイト順序の情報をCDRから取り出し、そのバイト順序情報を受信側のCDRにセットします。それからCDRに詰められている各情報を取得します。取得はやはりACE_CDRに定義されている型となります。

ファイル・ソケットなどのバイトストリーム越しの送受信データは、このCDRを使ってあげれば、エンディアンやパディングが異なっても気にすることなくすみます。

ACE_CDRの各型一覧
CDR型 ACE定義型 C++
ACE_CDR::Boolean - bool
ACE_CDR::Octed - unsigned char
ACE_CDR::Char - char
ACE_CDR::Short ACE_INT16
ACE_CDR::UShort ACE_UINT16
ACE_CDR::LONG ACE_INT32
ACE_CDR::ULong ACE_UINT32
ACE_CDR::ULongLong ACE_UINT64
ACE_CDR::LongLong - long long