プロが教えるわが家の防犯対策術!

C#で16進バイナリ文字列連結
C#にてシリアル通信の勉強を始めたばかりなのですが
早速初っ端の基礎から解らず立ち往生しています。

ushort a=0x0050;
byte b = 0x00;
byte c = 0xff;
ushort d = 0x03ff;
byte e = 0x00;
ushort f = 0x000c;
と16進数値が居ます。
これを、リトルインディアン形式で連結させて
50 00 00 ff ff 03 00 0c 00
という電文にしたいのですが、どうやって繋げたらいいのでしょうか?
今まで"アスキー文字列"を単に繋げて送出したことしかなくて、いざバイナリ形式でやってみようとして
うろたえてます。

A 回答 (4件)

http://ideone.com/EXiGX

無駄に回りくどいのは、「System.BitConverter.GetBytesがEndianによって異なる結果を返すのに対応しようとしたこと」と、「配列よりListの方が好み」という2点による。

http://msdn.microsoft.com/en-us/library/system.b …

配列で欲しけりゃToArray()メソッドでも実行しておくれ。
http://msdn.microsoft.com/en-us/library/x303t819 …

この回答への補足

お手数ですが
x.ForEach(delegate(List<byte> list)・・・
y.ForEach(delegate(byte b1)・・・
ForEachな処理なんだなぁとは思うも続くデリゲートという言葉に私のオツムがバリケードです
理解の範囲を超越してしまってます。
バイト型のジェネリックなList型のlistに委譲・・・???
日本語で考えてみても所詮無い知恵。とっかかりにも掴めません。
もしよろしければ、この行の仕組みを少し解説してはいただけませんでしょうか?
List<T>.ForEach メソッド をMSDNのヘルプで読んでいるのですが
「Action<T> は、渡されたオブジェクトに対して処理を実行するメソッドのデリゲートです。」
と書かれてあっても、まだ意味するところがチンプンカンプンなんです。

補足日時:2010/08/24 23:38
    • good
    • 0
この回答へのお礼

これぞC# !という内容でびっくりしました。
凄い。凄い。凄ぇ。へぇ~と感心しきりです。
実はジェネリック初体験です。F11キー連打しながらお勉強中です。
また新しい事柄をひとつ覚えることが出来ました。ありがとうございます。

お礼日時:2010/08/24 23:48

#3です。

返答が遅れて申し訳ないです。

補足について
>SendMessage構造体の中身が、連続したメモリを確保しFieldOffsetで指定した位置から順に配置してくれるそんなイメージで良いでしょうか?

はい、そのとおりです。バイナリファイル(画像ファイル等)やバイナリデータを通信でやりとりする場合に使用します。リトルエンディアンのプロセッサでは、メモリに配置されたバイナリデータは希望どうりのリトルエンディアンに整列されていますから、それをメモリアドレスに沿ってバイト単位で順番にアクセスすればリトルエンディアンのデータとして読み出すことが可能です。

>配列のサイズは変数宣言の中で指定できません ('new' を使用して初期化してください)
>この部分はいったい何を?

私のミスです。C#が使用できる環境になかったので適当に書いてしまいました。いい加減な回答で申し訳ありませんでした。C#で記述すると「構文エラー」になります。

>この 構造体を文字列に変換するだけ の手順が解りません。

byte message[12];をbyte messageとしてポインターに代入してアクセスします。
unsafe 修飾子を付加した関数を作成するとC言語と同じ要領でアクセス可能です。

この方法は、インテルのプロセッサーがリトルエンディアンであり、.NETフレームワークが今のところインテルのプロセッサー及び互換以外のPCには提供されていないことを前提とした機種依存のプログラムになります。
将来もそうであるとは限りませんから、機種依存を回避するには#2の回答のようなプログラムが正解です。
    • good
    • 0
この回答へのお礼

目的や方向は同じでも、そこに辿りつくまでの道にはいろんな手段があるということが解り
たいへん勉強になりました。ありがとうございます。

お礼日時:2010/09/07 21:49

System.Runtime.InteropServices 名前空間のFieldOffsetクラスを使った共用体を作ってしまうのも手です。


struct SendMessage {
[System.Runtime.InteropServices.FieldOffset(0)]
public byte message[12]; //アライメント調整で12にしてある
[System.Runtime.InteropServices.FieldOffset(0)]
public ushort a;
[System.Runtime.InteropServices.FieldOffset(2)]
public byte b;
[System.Runtime.InteropServices.FieldOffset(3)]
public byte c;
[System.Runtime.InteropServices.FieldOffset(4)]
public ushort d;
[System.Runtime.InteropServices.FieldOffset(6)]
public byte e;
[System.Runtime.InteropServices.FieldOffset(7)]
public ushort f;
}

あとは、インテルのプロセッサはリトルエンディアンなのでメンバーのmessageを文字列に変換するだけですね。

参考URL:http://msdn.microsoft.com/ja-jp/library/acxa5b99 …

この回答への補足

SendMessage構造体の中身が、連続したメモリを確保しFieldOffsetで指定した位置から順に配置してくれる
そんなイメージで良いでしょうか?

[System.Runtime.InteropServices.FieldOffset(0)]public byte message[12];
がエラーになりますが
配列のサイズは変数宣言の中で指定できません ('new' を使用して初期化してください)
この部分はいったい何を?

この 構造体を文字列に変換するだけ の手順が解りません。
String str=SendMessage.a & SendMessage.b & SendMessage.c &・・・
ん?FieldOffsetで数珠繋ぎになってるのに、なんで1個ずつ拾わないと・・・おかしいなぁ。

つまり、てんで解ってません。補足お願いします。

補足日時:2010/08/28 19:33
    • good
    • 0

こんな感じ。



string msg =
string.Format("{0:x2} {1:x2} ",a & 0xff, (a & 0xff00) >> 8) +
string.Format("{0:x2} ", b) +
string.Format("{0:x2} ", c) +
string.Format("{0:x2} {1:x2} ",d & 0xff, (d & 0xff00) >> 8) +
string.Format("{0:x2} ", e) +
string.Format("{0:x2} {1:x2} ",f & 0xff, (f & 0xff00) >> 8);
    • good
    • 0
この回答へのお礼

おお、これなら付いていけます。私のオツムが。

a >> 8 としないで
(a & 0xff00) >> 8
と念を押しているのは、視覚的に後で追い易い為でしょうか?
それとも何かの温床になる為にこうして置いた方が良いのでしょうか?
すみません、つまらぬところでつまづいていて。
段差の無い所でもけつまづく。ちょっとづつ一歩一歩学習していきます。
この度はありがとうございました。

お礼日時:2010/08/25 00:18

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