tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルbyte型として構造体のデータを扱いたい
記事No9804
投稿日: 2010/01/20(Wed) 20:21
投稿者ジョジョ
.net 2005 vbで2ヶ月の経歴になります。
    TCPIPの通信で使用予定のことですがbyteデータでの
  引数になっているのでその型にあわせたいのですが。

  下記のsend_msgにwk_msgをいれる方法が存在するのか、
    wk_msgをbyte型のデータにできるのかを教えていただきたく思います。
    
    Structure MsgHead
        Dim size As Integer
        Dim moji As String
    End Structure

    Dim wk_msg As New MsgHead

    wk_msg.size = 5 + 8       '5文字+integer
    wk_msg.moji = "abcdef"

    Dim send_msg() As Byte
    ReDim send_msg(13)

  ------
    ReDim send_msg(8)
    のときにwk_msg.sizeをいれるにはどうのようにすればいいのでしょうか

[ツリー表示へ]
タイトルRe: byte型として構造体のデータを扱いたい
記事No9806
投稿日: 2010/01/20(Wed) 21:38
投稿者Hongliang
基本的に自分で各プロパティごとに変換していくことになります。
Integer なら BitConverter.GetBytes(ただしエンディアン固定なので注意)。
String なら Encoding.GetBytes が使えるでしょう。
末尾に NULL 文字が必要かとか、エンコーディングはどうするのかと言った問題はあります。
これらで取得したバイト配列の結合は、両者の長さを合計した配列を新しく作り、
それぞれ適切な位置にコピーするようにするのが分かりやすいでしょう。
VB の Dim や ReDim で配列を確保する際の添え字は「配列の最大インデックス」です。
配列は 0 からインデックスを持つため、Dim a(1) As Integer とした場合、
要素数は 2 になることに注意してください。(a(0) と a(1) の 2 要素です)

> wk_msg.size = 5 + 8       '5文字+integer
> wk_msg.moji = "abcdef"
abcdef は 6 文字ですし、Integer は通常 4 bytes です。
この 5 や 8 はどこから出てきたのでしょうか……?

> ReDim send_msg(8)
> のときにwk_msg.sizeをいれるにはどうのようにすればいいのでしょうか
先に String の方を Bytes に変換し、
それの Length + 4 を BitConverter で変換するようにすればいいんじゃないでしょうか?
そもそもユーザには size を見せる(プロパティにする)必要はなく、
送受信時のみ size を計算するだけで良さそうですけど。

[ツリー表示へ]
タイトルRe^2: byte型として構造体のデータを扱いたい
記事No9807
投稿日: 2010/01/20(Wed) 23:08
投稿者ジョジョ
レスありがとうございます。

> 基本的に自分で各プロパティごとに変換していくことになります。
> Integer なら BitConverter.GetBytes(ただしエンディアン固定なので注意)。
> String なら Encoding.GetBytes が使えるでしょう。
BitConverter.GetBytesではサイズ分(下記の部分も修正します)が確保されるようですね。

> > wk_msg.size = 5 + 8       '5文字+integer
> > wk_msg.moji = "abcdef"
  文字は6文字でした。Encoding.GetBytesで可変にできますね。
  integerは.net2008をみていたようです。すいません。

  ReDim send_msg_size() as byte = BitConverter.GetBytes( wk_msg.size )
    ReDim send_msg_moji() as byte = Encoding.GetBytes( wk_msg.moji )
    
    send_msg = send_msg_size & send_msg_moji
    (send_msgの領域省略しました。現在環境がないなかで申し訳ありません)
  で結合ができるという感じですかね。

[ツリー表示へ]
タイトルRe^3: byte型として構造体のデータを扱いたい
記事No9808
投稿日: 2010/01/20(Wed) 23:52
投稿者魔界の仮面弁士
> > > wk_msg.size = 5 + 8       '5文字+integer
> > > wk_msg.moji = "abcdef"
>   文字は6文字でした。Encoding.GetBytesで可変にできますね。
>   integerは.net2008をみていたようです。すいません。
Integer 型=System.Int32 構造体です。

2008 (.NET Framework 3.5) であっても、
Integer のサイズは 4 バイト(32 bit)ですよ。


>     send_msg = send_msg_size & send_msg_moji
>     (send_msgの領域省略しました。現在環境がないなかで申し訳ありません)
>   で結合ができるという感じですかね。
Byte 配列を & 演算子で連結する事はできないので、
Array.Copy メソッドで、send_msg に転記しましょう。

あるいは、
  Dim buf As New List(Of Byte)()
  buf.AddRange(BitConverter.GetBytes(wk_msg.size))
  buf.AddRange(Encoding.ASCII.GetBytes(wk_msg.moji))
  Dim send_msg() As Byte = buf.ToArray()
という方法もあります。


このほか、MemoryStream を使うという手もあります。
(StreamWriter 経由で書き込み、StreamReader 経由で読み込み)

[ツリー表示へ]
タイトルRe^4: byte型として構造体のデータを扱いたい
記事No9809
投稿日: 2010/01/21(Thu) 11:00
投稿者ジョジョ
レスありがとうございます。
度重なるミスをして申し訳ありません。

> > > > wk_msg.size = 5 + 8       '5文字+integer
> > > > wk_msg.moji = "abcdef"
> >   文字は6文字でした。Encoding.GetBytesで可変にできますね。
> >   integerは.net2008をみていたようです。すいません。
> Integer 型=System.Int32 構造体です。
>
> 2008 (.NET Framework 3.5) であっても、
> Integer のサイズは 4 バイト(32 bit)ですよ。

大変申し訳ありません。何を血迷ったか大きすぎる間違いでした。

ReDim send_msg_size() as byte = BitConverter.GetBytes( wk_msg.size )
これだと
    wk_msg.size = 256
    の値は 00 00 01 00のイメージで
    send_msg_sizeでは
        00 01 00 00になっているようですが上位と下位をいれかえる必要が
        あるのでしょうか?
> >     send_msg = send_msg_size & send_msg_moji
> >     (send_msgの領域省略しました。現在環境がないなかで申し訳ありません)
> >   で結合ができるという感じですかね。
> Byte 配列を & 演算子で連結する事はできないので、
> Array.Copy メソッドで、send_msg に転記しましょう。

    ReDim send_msg_size() as byte = BitConverter.GetBytes( wk_msg.size )
    ReDim send_msg_moji() as byte = Encoding.GetBytes( wk_msg.moji )
    Array.Copy( send_msg_size, send_msg, send_msg_size.length)
    Array.Copy( send_msg_size, send_msg_moji, send_msg_size.length)
        
    Array.Copyはスタートポジションはどのようになっているのでしょうか?

> あるいは、
>   Dim buf As New List(Of Byte)()
    Listはどういう型を記述すればいいのでしょうか?
>   buf.AddRange(BitConverter.GetBytes(wk_msg.size))
>   buf.AddRange(Encoding.ASCII.GetBytes(wk_msg.moji))
>   Dim send_msg() As Byte = buf.ToArray()
> という方法もあります。

[ツリー表示へ]
タイトルRe^5: byte型として構造体のデータを扱いたい
記事No9810
投稿日: 2010/01/21(Thu) 11:33
投稿者魔界の仮面弁士
>     send_msg_sizeでは
>         00 01 00 00になっているようですが上位と下位をいれかえる必要が
>         あるのでしょうか?
エンディアンについては、『TCPIPの通信で使用予定』のデータ形式次第だと思いますが、
ジョジョさんがそれをどのように使うのか分からないので、私には答えられないです。


>     Array.Copyはスタートポジションはどのようになっているのでしょうか?
Array.Copy(Array, Array, Integer) のオーバーロードではなく、
Array.Copy(Array, Integer, Array, Integer, Integer) の方を使えば、
コピー先配列の任意のエリアに転記することが出来ます。


> >   Dim buf As New List(Of Byte)()
>     Listはどういう型を記述すればいいのでしょうか?
?? 質問の意味が良く分かりませんが、どういう型も何も、
見ての通りの List というジェネリック型なので、上記をそのまま記述すれば OK です。

名前空間まで記述するなら、System.Collection.Generic.List(Of System.Byte) 型です。

[ツリー表示へ]
タイトルRe^6: byte型として構造体のデータを扱いたい
記事No9814
投稿日: 2010/01/21(Thu) 20:07
投稿者ジョジョ
> >     send_msg_sizeでは
> >         00 01 00 00になっているようですが上位と下位をいれかえる必要が
> >         あるのでしょうか?
> エンディアンについては、『TCPIPの通信で使用予定』のデータ形式次第だと思いますが、
> ジョジョさんがそれをどのように使うのか分からないので、私には答えられないです。
 変換する必要がありました。
 WinsockのDLLにあるみたいですがとりあえず、上位と下位をいれかえました。

> >     Array.Copyはスタートポジションはどのようになっているのでしょうか?
> Array.Copy(Array, Integer, Array, Integer, Integer) の方を使えば、
> コピー先配列の任意のエリアに転記することが出来ます。
すいません。そのとうりありました。

> > >   Dim buf As New List(Of Byte)()
> >     Listはどういう型を記述すればいいのでしょうか?
> ?? 質問の意味が良く分かりませんが、どういう型も何も、
> 見ての通りの List というジェネリック型なので、上記をそのまま記述すれば OK です。
 直書きしたら、おこられたもので名前空間からお勉強させてもらいました。
 
 Byte型へのいれることができました。
 魔界の仮面弁士さん、Hongliangさん
 大変ありがとうございました。
 

[ツリー表示へ]