アプリ版:「スタンプのみでお礼する」機能のリリースについて

(1)リトルエンディアン
typedef struct recvData{
 int a;
 unsigned char b[16];
unsigned char c[8];
unsigned int d[4];
} recvData_t;

recvData_t rData;


(2)ビッグエンディアン
typedef struct sendData{
 int a;
 unsigned int b[4];
unsigned int c[2];
unsigned int d[4];
} sendData_t;

sendData_t sData;

上記のようなリトルエンディアンの構造体の各メンバのデータを、ビッグエンディアンの構造体の各メンバのデータにそれぞれ格納するには
どうしたらよいでしょうか?

A 回答 (8件)

○「リトルエンディアンの構造体」とか「ビッグエンディアンの構造体」というのは、残念ながら見たことがありません。



○質問の文章からだと

rData.bにリトルエンディアンで8ビット*4(=32ビット)が4つ入っている
→これをsData.b (int型 [4] )に
rData.cにリトルエンディアンで8ビット*4(=32ビット)が2つ入っている
→これをsData.c (int型 [2])に

とも

rData.bにリトルエンディアンで8ビット*16(=128ビット)が1つ入っている
→これをsData.b (int型 [4] )をまとめて1つの128ビットと見做してビッグエンディアンに
rData.cにリトルエンディアンで8ビット*8(=64ビット)が1つ入っている
→これをsData.c (int型 [2])にまとめて1つの64ビットと見做してビッグエンディアンに

とも解釈できます。あなたのやりたいのは何でしょう?

○ .a, .dはそのままでいいのでしょうか?

○動かそうとしている計算機では、intの内部表現がビッグエンディアンになっていることは確認していますか?

○ unsigned intが32ビットだとして、ベタな方法はビットシフトとビット毎のorを使うものでしょう
unsigned int ui = (b[0] << 24) | (b[1] << 16) | ( b[2] << 8 ) | (b[3]) ;
なんども使うなら、マクロなり関数なりにすればいいです。

この回答への補足

○b,cについては、やりたいのは、以下の指摘の方です。

-----------------------------------------------------------------------------
rData.bにリトルエンディアンで8ビット*16(=128ビット)が1つ入っている
→これをsData.b (int型 [4] )をまとめて1つの128ビットと見做してビッグエンディアンに
rData.cにリトルエンディアンで8ビット*8(=64ビット)が1つ入っている
→これをsData.c (int型 [2])にまとめて1つの64ビットと見做してビッグエンディアンに
-------------------------------------------------------------------------------

○a,dについてもリトルからビッグに変換が必要なので、

sData.a = htonl(rData.a);のように関数を実行すれば問題ないでしょうか?

dの方はどうすればよいでしょうか?

○動かそうとしているハードは、intをビッグエンディアンになっていることは確認済みす。

よろしくお願い致します。

補足日時:2012/05/24 07:57
    • good
    • 0

その後、エンディアン変換は成功されたでしょうか。



補足の「sData.b (int型 [4] ) をまとめて1つの128ビットと見做して」という点は確かでしょうか? 間違いなければ、下のような処理で期待される結果が得られると思いますけれども...

union {
recvData_t in;
sendData_t out;
} rData;
sendData_t sData;

rData.in = anyData; /* 何らかのrecvData_tデータをセット */

sData.a = htonl(rData.out.a);
sData.b[0] = htonl(rData.out.b[0]);
sData.b[1] = htonl(rData.out.b[1]);
sData.b[2] = htonl(rData.out.b[2]);
sData.b[3] = htonl(rData.out.b[3]);
sData.c[0] = htonl(rData.out.c[0]);
sData.c[1] = htonl(rData.out.c[1]);
sData.d[0] = htonl(rData.out.d[0]);
sData.d[1] = htonl(rData.out.d[1]);
sData.d[2] = htonl(rData.out.d[2]);
sData.d[3] = htonl(rData.out.d[3]);

sendData_t tmp = sData;

sData.b[0] = tmp.b[3];
sData.b[1] = tmp.b[2];
sData.b[2] = tmp.b[1];
sData.b[3] = tmp.b[0];
sData.c[0] = tmp.c[1];
sData.c[1] = tmp.c[0];
sData.d[0] = tmp.d[3];
sData.d[1] = tmp.d[2];
sData.d[2] = tmp.d[1];
sData.d[3] = tmp.d[0];
    • good
    • 0

どうでもいいことかもしれませんがhtonl()を「リトルエンディアンからビッグエンディアンに変換する関数」とは覚えないでください。


Host byte order TO Network byte orderなのでホストにより変わります。
    • good
    • 0

(1) と (2) のそれぞれで各データがメモリ上どのようになっているのかを絵に描いて


「これをこうしたいからこんな操作が必要だよね」
って考えればいいだけじゃないのかなぁ....
    • good
    • 1

何か誤解を招きそうな表現や嘘書いてるし・・・



>htol()やhtonl()はビッグエンディアンのマシンにもありますよ。

htol()でなくてhtons()です。

>何もしないだけで。

「何もせず引数の値をそのまま返す」です。

申し訳ありません。
    • good
    • 0

>#2さんへ


htol()やhtonl()はビッグエンディアンのマシンにもありますよ。
何もしないだけで。
    • good
    • 0

a,dについては、#1さんの言う通り、ビットシフトでやるなり、bswap()やhtonl()


なりで変換してください。(htonlはx86やIA64の様に、リトルのCPUのみですが)
b,cはバイトですよね?バイトにはエンディアン関係ないし、型が異なっています。
どう格納したいのですか?
    • good
    • 0

変換する関数なりなんなりを手で書く.

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!