構造体

Similar documents
構造体

ファイル操作-バイナリファイル

プロセス間通信

ICONファイルフォーマット

VB6互換のファイルの処理

ファイル操作-インターネットキャッシュ

Visual Basic 資料 電脳梁山泊烏賊塾 コレクション初期化子 コレクション初期化子 初めに.NET 版の Visual Basic では 其れ迄の Visual Basic 6.0 とは異なり 下記の例の様に変数宣言の構文に 初期値を代入する式が書ける様に成った 其の際 1 の様に単一の値

ファイル操作

ウィンドウ操作 応用

mySQLの利用

正規表現応用

VB実用Ⅲ⑩ フリーデータベースⅡ

VB.NET解説

ListViewコントロール

ハッシュテーブル

DAOの利用

グラフィックス

Userコントロール

プラグイン

Microsoft Word 練習問題の解答.doc

PYTHON 資料 電脳梁山泊烏賊塾 PYTHON 入門 関数とメソッド 関数とメソッド Python には関数 (function) とメソッド (method) が有る モジュール内に def で定義されて居る物が関数 クラス内に def で定義されて居る物がメソッドに成る ( 正確にはクラスが

ICONファイルフォーマット

PowerPoint プレゼンテーション

C 資料 電脳梁山泊烏賊塾 ファイルの入出力 C++ のバイナリファイル入出力 初めに 此処では Visual Studio 2017 を起動し 新しいプロジェクトで Visual C++ の Windows デスクトップを選択し Windows コンソールアプリケーションを作成する

シーケンシャルファイルの操作

データアダプタ概要

NotifyIconコントロール

ルーレットプログラム

PYTHON 資料 電脳梁山泊烏賊塾 PYTHON 入門 文字列 文字列リテラル プログラムの中で文字列を表す方法は幾つか有るが 基本的な方法は下記の 2 種で有る 対象と成る文字の集まりをダブルクオーテーション ( " ) で囲うか シングルクオーテーション ( ' ) で囲う PYTHON3 "

回文作成支援プログラム

何時何処で誰が

PYTHON 資料 電脳梁山泊烏賊塾 PYTHON 入門 ゲームプログラミング スプライト スプライト Pygame では pygame.sprite を用いる事でスプライトの管理 描画 衝突判定等を簡単に行う事が出来る 此れを利用してキャラクター操作に関する各種機能をスプライトクラスとして 1 個

VB 資料 電脳梁山泊烏賊塾 音声認識 System.Speech の利用 System.Speech に依るディクテーション ( 音声を文字列化 ).NetFramework3.0 以上 (Visual Studio 2010 以降 ) では 標準で System.Speech が用意されて居るの

Microsoft PowerPoint - kougi9.ppt

Microsoft Excel操作

ファイル監視

C 資料 電脳梁山泊烏賊塾 構造体 C++ の構造体 初めに 此処では Visual Studio 2017 を起動し 新しいプロジェクトで Visual C++ の Windows デスクトップを選択し Windows コンソールアプリケーションを作成する 定義と変数宣言 C++ に

MISAO with WPF

Microsoft Word - DT-5100Lib_Manual_DotNet.doc

相性占いプログラム

PowerPoint プレゼンテーション

.NETプログラマー早期育成ドリル ~VB編 付録 文法早見表~

万年暦プログラム

第 2 章インタフェース定義言語 (IDL) IDL とは 言語や OS に依存しないインタフェース定義を行うためのインタフェース定義言語です CORBA アプリケーションを作成する場合は インタフェースを定義した IDL ファイルを作成する必要があります ここでは IDL の文法や IDL ファイ

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

相性占いプログラム

Prog2_12th

チア ダンス

JavaプログラミングⅠ

グラフィックス 目次

グラフィックス 目次

VB実用⑦ エクセル操作Ⅰ

モグラ叩きプログラム

ADO.NETのアーキテクチャ

プレポスト【問題】

API 連携方式 外部 DLL の呼び出し宣言 外部 DLL の呼び出し宣言のサンプルコード (Microsoft Visual C#.NET の場合 ) プログラムコードの先頭で using System.Runtime.InteropServices; が必要 クラスの内部に以下のような外部 D

スレッド操作 タイマー

ブロック パニック

Microsoft Word - no103.docx

64bit環境で32bitコンポーネントの利用

Prog1_10th

PowerPoint プレゼンテーション

バスケットボール

回文作成支援プログラム

Prog1_6th

ウィンドウ操作 詳細

コードページ

データベース1

基礎計算機演習 実習課題No6

Agenda Windows 64-bit 概要マネージコード開発 ( 導入 ) マネージコード開発 ( 詳細 ) コーディング上の留意点まとめ

画像閲覧プログラム

3D回転体プログラム

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

GS1-128 の描画 DLL について (ver. 2.3) 動作環境など動作環境 WindowsXP Windows Vista Windows7 Windows8/8.1 Windows10 上記 OS について すべて日本語版を対象としております 32bit アプリケーションから呼び出される

プログラミングI第10回

Microsoft Word _VBAProg1.docx

オブジェクト指向プログラミング・同演習 5月21日演習課題

Microsoft Word - no12.doc

メソッドのまとめ

Prog1_10th

Socketクラス

ランボール

データベース1

データベース1

Microsoft PowerPoint - kougi8.ppt


sinfI2005_VBA.doc

MS Office オートメーション

Microsoft PowerPoint - CproNt02.ppt [互換モード]

データベースプログラミング

正規表現概要

スライド 1

占領双六ゲーム

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

回文作成支援プログラム

Microsoft PowerPoint - lec10.ppt

Microsoft PowerPoint - 13th.ppt [互換モード]

回文作成支援プログラム

Microsoft Word - no15.docx

正規表現詳細

Transcription:

構造体 Byte 配列 構造体とコピーする方法 構造体とバイト配列の変換を行うには System.Runtime.InteropServices 名前空間をインポートして置くと便利で有る Imports System.Runtime.InteropServices using System.Runtime.InteropServices; 下記の 3 種類の構造体にバイト配列の値を格納した場合に付いて検証する Type1 構造体は総ての要素が Short 型の場合で Type2 と Type3 は最初の要素が Short 型 2 番目の要素が Integer 型 3 番目と 4 番目の要素が Bute 型で 構造体の長さ ( 総バイト数 ) は孰れも 8 バイトで有る 猶 3 番目の構造体は System.Runtime.InteropServices.StructLayout 属性で構造体のメモリ内での配置をカスタマイズして居る Private Structure Type1 Dim Item1 As Short Dim Item2 As Short Dim Item3 As Short Dim Item4 As Short End Structure Private Structure Type2 Dim Item1 As Short Dim Item2 As Integer Dim Item3 As Byte Dim Item4 As Byte End Structure <StructLayout(LayoutKind.Sequential, Pack:=1)> Structure Type3 Dim Item1 As Short Dim Item2 As Integer Dim Item3 As Byte Dim Item4 As Byte End Structure private struct type1 public short item1; public short item2; public short item3; public short item4; -1-

private struct type2 public short item1; public int item2; public byte item3; public byte item4; [StructLayout(LayoutKind.Sequential,Pack=1)] private struct type3 public short item1; public int item2; public byte item3; public byte item4; 因みに System.Runtime.InteropServices.StructLayout 属性で指定する LayoutKind 列挙型は 下記の通りで有る 属性 Auto Explicit Sequential 解説ランタイムは アンマネージメモリ内のオブジェクトのメンバに対して適切なレイアウトを自動的に選択する 此の列挙体メンバで定義されたオブジェクトは マネージコードの外に公開出来ない 公開しようとすると 例外が生成される アンマネージメモリ内に有るオブジェクトの各メンバの正確な位置は 明示的に制御される 各メンバは FieldOffsetAttribute を使用して 其の型内のフィールドの位置を指定する必要が有る オブジェクトのメンバは アンマネージメモリにエクスポートする時に表示される順番に従ってレイアウトされる メンバは StructLayoutAttribute.Pack で指定したパッキングに従ってレイアウトされる メンバは非連続に出来る 上記の夫々の構造体に格納するバイト配列の各要素の値は 下記の通りで有る 25H 52H 9AH 44H 16H 42H 21H 2CH 上記に対して 下記のコードを実行した結果を検証して観る Dim B() As Byte = &H25, &H52, &H9A, &H44, &H16, &H42, &H21, &H2C Dim T1 As Type1 Dim T2 As Type2 Dim T3 As Type3 Dim P1 As System.IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(Type1))) Dim P2 As System.IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(Type2))) Dim P3 As System.IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(Type3))) Marshal.Copy(B, 0, P1, B.Length) Marshal.Copy(B, 0, P2, B.Length) Marshal.Copy(B, 0, P3, B.Length) T1 = DirectCast(Marshal.PtrToStructure(P1, GetType(Type1)), Type1) -2-

T2 = DirectCast(Marshal.PtrToStructure(P2, GetType(Type2)), Type2) T3 = DirectCast(Marshal.PtrToStructure(P3, GetType(Type3)), Type3) System.Runtime.InteropServices.Marshal.FreeHGlobal(P1) System.Runtime.InteropServices.Marshal.FreeHGlobal(P2) System.Runtime.InteropServices.Marshal.FreeHGlobal(P3) byte[] b = 0x25, 0x52, 0x9A, 0x44, 0x16, 0x42, 0x21, 0x2C ; type1 t1; type2 t2; type3 t3; IntPtr p1 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(type1))); IntPtr p2 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(type2))); IntPtr p3 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(type3))); Marshal.Copy(b, 0, p1, b.length); Marshal.Copy(b, 0, p2, b.length); Marshal.Copy(b, 0, p3, b.length); t1 = (type1)marshal.ptrtostructure(p1, typeof(type1)); t2 = (type2)marshal.ptrtostructure(p2, typeof(type2)); t3 = (type3)marshal.ptrtostructure(p3, typeof(type3)); Marshal.FreeHGlobal(p1); Marshal.FreeHGlobal(p2); Marshal.FreeHGlobal(p3); 上記のコードを実行して DataGridView コントロールに各構造体の要素を表示したのが下図で有る Type1 構造体の様に各要素が同じデータ型で有れば正しく格納されるが Type2 構造体の様に各要素のデータ型が異なれば正しく格納されない 亦 Type3 構造体の様にアライメントを指定して構造体を定義すると 正しく格納される 猶 Pack:=1 の部分を Pack:=2 Pack:=4 Pack:=8 とすると 何う成るかも示して置く Pack:=1-3-

Pack:=2 Pack:=4 Pack:=8-4-

構造体 Byte 配列とコピーする方法 下記の構造体の値をバイト配列に格納した場合に付いて検証する 構造体は要素は総て最も問題と成る固定長の String 型にして有る 猶 構造体は System.Runtime.InteropServices.StructLayout 属性で構造体のメモリ内での配置をカスタマイズして居り 亦 固定長文字列を必要とする のファイル入出力関数 (FileGet や FilePut 等 ) を使う時の為に VBFixedStringAttribute 属性を使用して居る 其の為 では の参照設定を追加して置く必要が有る 猶 此の構造体には 構造体の要素をバイト配列に格納する為のユーザー定義関数 (Getbyte) が含まれて居る <StructLayout(LayoutKind.Sequential, Pack:=1)> Structure Buffer <VBFixedString(3), MarshalAs(UnmanagedType.ByValTStr, SizeConst:=3)> _ Dim Item1 As String <VBFixedString(3), MarshalAs(UnmanagedType.ByValTStr, SizeConst:=3)> _ Dim Item2 As String Function Getbyte(ByVal Data As Buffer) As Byte() Dim Num As Integer Dim Cnt As Integer Dim Buf() As Byte Dim Tmp() As Byte Num = Marshal.SizeOf(Data) ReDim Buf(Num - 1) Cnt = 0 Tmp = System.Text.Encoding.GetEncoding("SHIFT_JIS").GetBytes(Data.Item1) For I As Integer = 0 To (Tmp.Length - 1) If Cnt > Buf.Length - 1 Then Exit For Buf(Cnt) = Tmp(I) : Cnt += 1 Next Tmp = System.Text.Encoding.GetEncoding("SHIFT_JIS").GetBytes(Data.Item2) For I As Integer = 0 To (Tmp.Length - 1) If Cnt > Buf.Length - 1 Then Exit For Buf(Cnt) = Tmp(I) : Cnt += 1 Next Getbyte = Buf End Function End Structure [StructLayout(LayoutKind.Sequential, Pack = 1)] private struct buffer [VBFixedString(3), MarshalAs(UnmanagedType.ByValTStr, SizeConst=3)] public string item1; [VBFixedString(3), MarshalAs(UnmanagedType.ByValTStr, SizeConst=3)] public string item2; public byte[] Getbyte(buffer data) int num; int cnt; byte[] buf; -5-

byte[] tmp; num = Marshal.SizeOf(data); buf = new byte[num]; cnt = 0; tmp = System.Text.Encoding.GetEncoding("SHIFT_JIS").GetBytes(data.item1); for (int i = 0; i < tmp.length; i++) if (cnt > buf.length - 1) break; buf[cnt] = tmp[i]; cnt++; tmp = System.Text.Encoding.GetEncoding("SHIFT_JIS").GetBytes(data.item2); for (int i = 0; i < tmp.length; i++) if (cnt > buf.length - 1) break; buf[cnt] = tmp[i]; cnt++; return buf; 因みに VBFixedStringAttribute 属性は 文字列の長さを文字数ではなくバイト数で指定する 猶 System.Runtime.InteropServices.StructLayout 属性に付いては前項を参照され度い 上記に対して 下記のコードを実行した結果を検証して観る Dim B() As Byte Dim T As Buffer With T.Item1 = txtitem1.text.item2 = txtitem2.text End With B = T.Getbyte(T) lstdisp.items.clear() For I As Integer = 0 To (B.Length - 1) lstdisp.items.add(b(i).tostring("x").padleft(2, "0"c) & " - " & Chr(B(I))) Next byte[] b; buffer t; t.item1 = txtitem1.text; t.item2 = txtitem2.text; -6-

b = t.getbyte(t); lstdisp.items.clear(); for (int i = 0; i < b.length; i++) lstdisp.items.add(b[i].tostring("x").padleft(2, '0') + " - " + System.Convert.ToChar(b[i]).ToString()); 上記のコードを実行して ListBox コントロールにバイト配列の要素を表示したのが下図で有る 構造体の夫々の要素が VBFixedStringAttribute 属性で指定したバイト数と等しい時は 正しく格納されるが 等しくない時は正しく格納されない 此れは VBFixedStringAttribute 属性は 此の属性に対応するメソッド ( 固定長文字列を必要とする の FileGet や FilePut 等のファイル入出力関数 ) 等に対する情報提供の為の属性で 可変長の文字列を固定長の文字列に変換する訳ではないからで有る 従って の FileSystem を使用してファイルに書き込めば VBFixedStringAttribute 属性で指定したバイト数と等しくない要素の値も正しく保存される 下記のコードでは 書き込んだファイルからバイト配列に読み込んで確認して居る 構造体のユーザー定義関数 (Getbyte) の中で 各要素のバイト数を Marshal.SizeOf メソッドで取得し 其のバイト数丈をバイト配列に格納する事が出来れば良いのだが String 型の要素の場合はサイズを取得する事が出来ない -7-

Dim B() As Byte Dim T As Buffer With T.Item1 = txtitem1.text.item2 = txtitem2.text End With Dim F As String = Application.StartupPath If Not F.EndsWith(" ") Then F &= " " F &= "temp.rnd" FileOpen(1, F, OpenMode.Random,,, 6) FilePut(1, T, 1) FileClose(1) B = Microsoft.VisualBasic.FileIO.FileSystem.ReadAllBytes(F) Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile(F) lstdisp.items.clear() For I As Integer = 0 To (B.Length - 1) lstdisp.items.add(b(i).tostring("x").padleft(2, "0"c) & " - " & Chr(B(I))) Next byte[] b; buffer t; t.item1 = txtitem1.text; t.item2 = txtitem2.text; string f = Application.StartupPath; if (!f.endswith(@" ")) f += @" "; f += "temp.rnd"; FileSystem.FileOpen(1, f, OpenMode.Random, OpenAccess.Write, OpenShare.Default, 6); FileSystem.FilePut(1, t, 1); FileSystem.FileClose(1); b = Microsoft.VisualBasic.FileIO.FileSystem.ReadAllBytes(f); Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile(f); lstdisp.items.clear(); for (int i = 0; i < b.length; i++) lstdisp.items.add(b[i].tostring("x").padleft(2, '0') + " - " + System.Convert.ToChar(b[i]).ToString()); -8-