リトルエンディアン→ビッグエンディアン

このQ&Aのポイント
  • リトルエンディアンの構造体のデータをビッグエンディアンの構造体に格納する方法は?
  • リトルエンディアンとビッグエンディアンの構造体の違いとは?
  • リトルエンディアンとビッグエンディアンのデータの変換方法を教えてください。
回答を見る
  • ベストアンサー

リトルエンディアン→ビッグエンディアン

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

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.5

○「リトルエンディアンの構造体」とか「ビッグエンディアンの構造体」というのは、残念ながら見たことがありません。 ○質問の文章からだと 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]) ; なんども使うなら、マクロなり関数なりにすればいいです。

yuji8000
質問者

補足

○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をビッグエンディアンになっていることは確認済みす。 よろしくお願い致します。

その他の回答 (7)

noname#208507
noname#208507
回答No.8

その後、エンディアン変換は成功されたでしょうか。 補足の「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];

  • wormhole
  • ベストアンサー率28% (1622/5658)
回答No.7

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

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

(1) と (2) のそれぞれで各データがメモリ上どのようになっているのかを絵に描いて 「これをこうしたいからこんな操作が必要だよね」 って考えればいいだけじゃないのかなぁ....

  • wormhole
  • ベストアンサー率28% (1622/5658)
回答No.4

何か誤解を招きそうな表現や嘘書いてるし・・・ >htol()やhtonl()はビッグエンディアンのマシンにもありますよ。 htol()でなくてhtons()です。 >何もしないだけで。 「何もせず引数の値をそのまま返す」です。 申し訳ありません。

  • wormhole
  • ベストアンサー率28% (1622/5658)
回答No.3

>#2さんへ htol()やhtonl()はビッグエンディアンのマシンにもありますよ。 何もしないだけで。

  • unacyo
  • ベストアンサー率51% (35/68)
回答No.2

a,dについては、#1さんの言う通り、ビットシフトでやるなり、bswap()やhtonl() なりで変換してください。(htonlはx86やIA64の様に、リトルのCPUのみですが) b,cはバイトですよね?バイトにはエンディアン関係ないし、型が異なっています。 どう格納したいのですか?

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

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

関連するQ&A

  • 最近のCPUのほとんどはリトルエンディアンかビッグエンディアンでしょうか?

    2000年あたり以降に出た Windows, Mac, Linuxに使われているCPUのほとんどはリトルエンディアンかビッグエンディアンでしょうか? また、たとえば以下のような方法でエンディアンを調べられると考えていいのでしょうか?(VC++です) #include <windows.h> void GetEndian4(char* c){ unsigned __int32 a=0x03020100; BYTE *b = (BYTE*)&a, i=4; while (i--) c[i]=b[i]; } ////////// const char e[4]={}; GetEndian4( const_cast<char*>(e) ); //eが 0,1,2,3 になればリトルエンディアン //3,2,1,0 になればビッグエンディアン //PDP-エンディアンだと 2,3,0,1 …のはず (または2択ならこれだけでも判断可能…?) short s=1; printf( *(char*)&s ? "リトルエディアン\n" : "ビッグエディアン\n" ); あとここでもアラインメントの問題が絡みますが、このように アラインメントが(2のべき乗だとして)大きいであろう方から小さいであろう方にキャストする分には安全で、逆に sizeof(short) == sizeof(char)*2 として char c[2]={1,0}; short s=*(short*)&c; というのは危険な場合がある、ということでしょうか? また、その場合は たとえばビッグエンディアンなら short s=(c[0]<<8)|c[1]; とすればいいでしょうか?

  • 異なる構造体のデータのコピー

    (1)で受け取った構造体のメンバのデータを (2)の構造体のメンバにコピーしたいと考えています。 (1) typedef struct _recvData{ int data01; int data02; char data03; char data 04; char data05; char data 06; char data07; char data08; char data09; char data10; char array01[16]; char array02[16]; } recvData; (2) typedef struct _sendData{ int header; int data01; int data02; char data03; char data 04; char data05; char data 06; char data07; char data08; char data09; char data10; int array01[4]; int array02[4]; } sendData; そこで2点ほどおしえていただきたく、お願い致します。 (1)構造体が微妙に異なるため、各メンバ変数に値をそれぞれ代入していくしか方法がないのでしょうか? (2)array01, array02はデータの型が異なる場合、データのコピーはどのようにしたらよいでしょうか?

  • 構造体を型の異なる構造体に代入

    C言語初心者です。 今回の質問は入力された構造体のメンバのデータを型の異なる構造体に代入したいのですが、毎回コンパイラにおこられてしまいます(汗)具体的には typedef struct MSG{ longint type; int flg; int Dt[64]; }t_msg; このDt[64]を以下の構造体に代入します。 typedef struct SC_MSG{ char a; char b; short c; char d; char e; short f; }t_sc_msg; その際、異なる関数で処理するため、 main(){ foo(&t_msg); }; void foo(t_msg *pt_msgdt){ t_sc_msg = (*pt_msgdt+8); ココがエラーになってしまいます。 何か、根本的な間違いをおかしている気がします。 ご指導の方、宜しくお願いします。 ちなみにOSはLinuxでコンパイラーはgccです。

  • 構造体を用いた特定数値抽出方法について

    こんばんは。 前回、複数回実行方法および構造体の初期化について質問させていただいた者です。 VC++.NET2003を用いてコンソールプログラミングを行っています。 以下に前回示しました構造体を示します。この構造体は4つの整数型のメンバをもっています。 このNpktメンバ変数には、10から11000まで10ずつカウントアップされた値が格納されています。10,20,30,40・・・100,110・・・・11000ということです。そこで、Npktが100,200,300・・・の時のgettime,rPkt,lossPktメンバの値を抽出しファイル出力させたいと思い、以下に示しますプログラムを記述しました。 しかし、10,20,30,40・・・100,110・・・490,510,520・・・ という仮に500がない場合が存在し、Npktが500の値を取得できずにかつそれ以降の600,700・・・1000などを取得できない状態になってしまいます。 そこで、500がない場合は改行をファイル出力し600を探索しだすという方法を考えたのですが、うまく記述できません。 もしよろしければ、ヒントや記述方法を教えていただけないでしょうか? よろしくお願い致します。 (1)構造体 #define MAX 2000 struct tag{  int Npkt;  int gettime;  int rPkt;  int lossPkt; }rdata[MAX]; (2)プログラム概要 while(rdata[e].Npkt!='\0'){  if(rdata[e].Npkt==sa){   de=100;   sa+=de;   fprintf(fp9,"%d\t%d\t%d\t%d\n",rdata[e].Npkt,rdata [e].gettime,rdata[e].rPkt,rdata[e].lossPkt);  }  e++; }

  • 1バイトデータの読み出しについて

    こんばんは。 すみません。文字操作?ポインタ操作が苦手なので教えてください。 以下のような構造体があり、その構造体から1バイトずつ読み出して 自作の関数のパラメータ(1バイト指定領域)に渡したいのですが、 構造体から1バイトずつデータを読み出すには、どのようにすればいいのでしょうか? typedef struct { PACKET_HEADER head; unsigned char Sp_Pr_St[1]; unsigned char ctrl_flow[1]; unsigned char product_org[10]; unsigned char product_name[10]; unsigned char product_ver[3]; }PRODUCT_RESPONS; typedef struct { unsigned char head; unsigned char type; unsigned char data_len; } HEADER; どうぞよろしくお願いします。

  • 構造体型のポインタ変数を含む構造体

    struct seiseki_tag { Int32 math ; Int32 english ; Int32 science; } ; typedef struct seiseki_tag SEISEKI ; struct personal_tag { Char name ; Int32 num ; SEISEKI *sptr } : typedef struct personal_tag PERSONAL ; struct info_tag { PERSONAL person_info ; } ; typedef struct info_tag INFO ; たとえば、上記のように3つの構造体があり、PERSONAL構造体のメンバーに SEISEKI構造体の型を持つポインタ変数が含まれているような場合で、下記のように INFO型のポインタ変数からSEISEKI構造体のメンバーを参照する方法を教えてください。 PERSONAL構造体メンバーのnameやnumは INFO *info ; info->person_info.name ; info->person_info.num ; のように参照すると思いますが、sptrが示すSEISEKI構造体のメンバーへの アクセスができません。下記のように参照を試みたのですがコンパイルは 通るのですが、実際に参照できていませんでした。 INFO *info ; SEISEKI *seiseki ; seiseki = info->person_info.sptr ; seiseki->math ; 判りにくい説明で申し訳ありませんが、どなたか教えていただければと思います。 よろしくお願いいたします。

  • 配列から構造体へデータコピー

    配列から構造体へデータのコピーをしたいのですが、 構造体のメンバがビットフィールドで構成されている時の処理がわかりません。 --------test.c----------- #include <stdio.h> #include <string.h> typedef struct{ unsigned char aaa :1; unsigned char bbb :1; unsigned char ccc :1; unsigned int ddd :13; unsigned char eee :2; unsigned char fff :2; unsigned char ggg :4; }test_t; int main(void) { test_t test_t; unsigned char data[]={0x5F, 0xFE, 0x1C}; memcpy(&test_t, data, 4); printf("aaa = %X\n", test_t.aaa); printf("bbb = %X\n", test_t.bbb); printf("ccc = %X\n", test_t.ccc); printf("ddd = %d\n", test_t.ddd); printf("eee = %X\n", test_t.eee); printf("fff = %X\n", test_t.fff); printf("ggg = %X\n", test_t.ggg); return 0; } ------期待出力--------- aaa = 0 bbb = 1 ccc = 0 ddd = 1FFE eee = 0 fff = 1 ggg = 12 「test.c」を実行した時に「期待出力」のような出力を期待していたのですが、実際には aaa = 1 bbb = 1 ccc = 1 ddd = 1 eee = 0 fff = 0 ggg = 0 と表示されてしまいます。 ビットフィールドで構成された構造体に、配列の値をそのままあてる事は出来ないのでしょうか? 出来るだけ、マスクやシフト演算を使用しないで、配列からビット単位で値を抽出したいのですが・・・

  • Javaでのエンディアン変換

    こんばんは☆ Javaでのエンディアン変換をご教授ください。 ファイルを読み込み、ソケット通信でサーバへデータ送信しています。 リトルエンディアンで送らなければいけないのですが、 Javaはプラットフォーム問わずにビッグエンディアンでメモリに格納するとありました。 そこで、バイトオーダーをしようと思い、 stirlingというバイナリエディタでバイナリファイルを作成して以下の2点で試しました。 <バイナリファイル構造体> struct stest { LONG l1; LONG l2; LONG l3; LONG l4; }; <バイナリデータ(数値)> 1234 (010000020000030000040000)←バイナリエディタで見たとき <テスト1結果> ・・・new InputStreamReader(in, "UnicodeLittle"); >1000200030004000 <テスト2結果> ByteBuffer buffer = ByteBuffer.wrap(bt); buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.get(); >1000200030004000 これはリトルエンディアンなのでしょうか? どちらも、 Javaで読み込み時にエンディアン指定しない時と出力結果に違いがありませんでした。 なぜでしょうか? ちなみに、データ型を意識せずに変換したいです。 色々と調べたのですが、良く分かりません。 どなたかご教授お願いいたしますm(_ _)m

    • ベストアンサー
    • Java
  • 値を返さないといけないのに、返さない関数の挙動

    こんな感じの構造体・関数を作ったとします。 typedef struct personal_info {    char name[10];    char address[20]; } personal_t; personal_t getPersonal(int id){;} これには2つのギモンがありまして 1.getPersonalの中は何もせず、値を返さないのに なぜか、コンパイルは通る 2.実行すると、正常に動く いったい、どういう事なのでしょうか。 不思議でたまりません。 どうぞよろしくお願いします。

  • free()について

    free()についてです。 よろしくお願いします。 ある構造体Aがあったとして その構造体Aの中に構造体Bのポインタが あったとします。 typedef struct{ char b; short c; } B_t; typedef struct { int a; B_t *bbb; } A_t; この構造体をプログラム中でポインタで扱い mallocで領域確保している場合に(A,B共に) Aをfree()した場合は、Bも開放されるのでしょうか? 以下、質問のサンプルです。 A_t *aaa; aaa = (A_t *)malloc(sizeof(A_t)); aaa->bbb = (B_t *)malloc(sizeof(B_t)); : : free(aaa); /* ←これで、aaaのメンバであるbbbは */ /* 開放されるのでしょうか? */ よろしくお願い致します。