2016-12-22 10 views
-1

プロジェクトでは、いくつかのプリミティブをシリアル化して、ローカルにホストされているJavaサーバーにワイヤを介して送信しようとしています。 Javaの部分はあまり重要ではありませんが、重要なのはJavaがビッグエンディアンとしてデータを解釈するのに対して、私のC++プログラムはLittle Endianです。エンディアンを念頭に置いてプリミティブを適切にシリアル化/シリアライズする

小さな例えば、私はダブルを持っている:

_fields.degLatitude = 50.0; 

は、私がそのデータをシリアル化したいのですが、また、バイト順(リトル>ビッグエンディアンに準拠するように)スワップ:

char buffer[sizeof(struct Fields)]; 
char* p = buffer; 

writeReversedData<double>(&p, _fields.degLatitude); 

writeReversedDataの実装はここにある:

template <typename T> void JsbSimWrapper::writeReversedData(char** bb, T& data) 
{ 
    const char* charBuffer = std::to_string(data).c_str(); 

    for (int i = 0; i < sizeof(T); i++) 
    { 
     (*bb)[i] = charBuffer[sizeof(T) - i - 1]; 
    } 

    *bb += sizeof(T); 
} 

は、それからちょうど私の側のテストとして、私はunseしたかったですそのデータをrialize戻っリトルエンディアンにそれを交換:

std::cout << getReversedData<double>(&p) << std::endl; 

そしてここではgetReversedDataの実装です:

template <typename T> T JsbSimWrapper::getReversedData(char** p) 
{ 
    union temp 
    { 
     char bytes[sizeof(T)]; 
     T tt; 
    }; 

    temp t; 

    for (int i = 0; i < sizeof(T); i++) 
    { 
     t.bytes[i] = (*p)[(sizeof(T) - 1) - i]; 
    } 

    *p += sizeof(T); 

    return t.tt; 
} 

残念ながら、COUTはちょうど50.0にさえ近くない膨大な数を返します。私はまた、Javaの終わりで受け取ったデータをテストし、それはC++のcoutと一致するので、私の書き込み呼び出しで何かでなければなりません。

私はgetReversedDataが動作していることを知っています。Java側でシリアル化されたデータを送信してテストしたので、C++側でそれを正しく解釈します。

答えて

1

このコードは、一時的なポインタを格納します。ステートメントが完了すると直ぐにぶら下がります。

const char* charBuffer = std::to_string(data).c_str(); 

また、forループ

for (int i = 0; i < sizeof(T); i++) 
{ 
    (*bb)[i] = charBuffer[sizeof(T) - i - 1]; 
} 

の文字列表現がsizeof(T)であるというルールが存在しません。たとえば、4バイトのintは10桁に変換されます。

std::stringに変換結果を格納し、その文字列のlength()を使用する方がはるかに良いでしょう。

関連する問題