- 締切済み
VB2005でバイト配列をコピーするには
どなたかご教授下さい。 VB6で作成したプログラムをVB2005にコンバートしました。構造体からなる配列変数を一つの配列変数にコピー したいのですが、構造体の最初のメンバーだけ値が同じで以降の値は正しくセットされていませんでした。 どのように記述したらよいのでしょうか。またCopymMemory以外で良い方法があればご教授下さい。 よろしくお願い致します。 ===概略=== Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Byte, ByRef Source As Byte, ByVal Length As Short) 構造体定義 (コピー元) <StructLayout(LayoutKind.Sequential)>Structure ST_MOTO <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Dim byte_strTranCd() As Byte <MarshalAs(UnmanagedType.ByValArray, SizeConst:=5)> Dim byte_strTanSeq() As Byte <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> Dim byte_strTxtNo() As Byte <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> Dim byte_strTxtSeq() As Byte End Structure Dim A As ST_MOTO (コピー先) <StructLayout(LayoutKind.Sequential)> Structure ST_SAKI Dim lngrecLen As Integer 'データのLength <MarshalAs(UnmanagedType.ByValArray, SizeConst:=100)> Dim bytrecData() As Byte 'データ End Structure Dim B As ST_SAKI Call CopyMemory(B.bytrecData(0), A.byte_strTranCd(0), 14) 出力結果 '最初の構造体のメンバーの値は正しく設定されている B.bytrecData(0) =80 A.byte_strTranCd(0) =80 B.bytrecData(1) =50 A.byte_strTranCd(1) =50 B.bytrecData(2) =57 A.byte_strTranCd(2) =57 B.bytrecData(3) =50 A.byte_strTranCd(3) =50 'これ以降は正しくない。(VB6だと正しく設定されている) B.bytrecData(4) =0 A.byte_strTanSeq(0) =80 B.bytrecData(5) =0 A.byte_strTanSeq(1) =87 B.bytrecData(6) =0 A.byte_strTanSeq(2) =48 B.bytrecData(7) =0 A.byte_strTanSeq(3) =48 B.bytrecData(8) =6 A.byte_strTanSeq(4) =55 ・ ・ ・ ・
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- himajin100000
- ベストアンサー率54% (1660/3060)
- himajin100000
- ベストアンサー率54% (1660/3060)
関連するQ&A
- ファイル入力のデータを構造体に入れる方法
VB.net(XP:VS2008のみフルインストール)にて テキストファイルから入力したデータを構造体st_testに入れたいと考えているのですが、実現できません。 どなたか、お力添えをお願いします。 テキストファイルは、事前に構造体(st_test)に値を入れ、 単純にFileOpen→OutPutしています。 (","や" "などでメンバ毎に分割等はしておりません。) 構造体 ---------------------- Public Structure st_test <VBFixedArray(63), MarshalAs(UnmanagedType.ByValArray, SizeConst:=64)> _ Dim A() As Byte Dim B As Integer <VBFixedArray(7), MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> _ Dim N() As Byte <VBFixedArray((7), (11)), MarshalAs(UnmanagedType.ByValArray, SizeConst:=(72))> _ Dim S(,) As Byte <VBFixedArray(11), MarshalAs(UnmanagedType.ByValArray, SizeConst:=12)> _ Dim U() As Integer End Structure ---------------------- 実現しようとしている個所 ---------------------- Dim t As String Dim temp(2) as st_test FileOpen(1, "test1.txt", OpenMode.Input) Input(FileNum, t) '''temp(0) = CType(CType(t, Object), st_test)...? temp(0) = CType(t, st_test) | FileOpen(1, "test2.txt", OpenMode.Input) Input(FileNum, t) temp(1) = CType(t, st_test) ---------------------- 上記の様に処理を行えば簡単にできるのかと安易な発想でいましたが、 CTypeの処理で'String'の値を'st_test'に変換できません。 旨のエラーになり、うまく実現することができません。 そもそもString型のデータをst_testにキャストすることが不可能なのでしょうか? それともただ、実現方法がカスなのでしょうか? 実際の構造体のサイズは4000Byteを超え(メンバ数も多いです。。。) 一つ一つ入力していくことが現実的に不可能なため ファイルよりInputすることしか思いついておりません。 test1.txtの中身を秀丸で開いてみました。 参考になれば・・・。 改行はなく、"福岡"の後等にそれぞれ空白があります。 -------------------------- 福岡 . A1 14 15 16 17 18 19 XX XX XX XX XX XX -------------------------- 宜しくお願いします。
- 締切済み
- Visual Basic
- VB2005のファイル読込でDo While Not EOFを使用するには?
いつもお世話になります。VB2005でテキストファイル(中身は1レコードのみ)をFileOpen関数の ランダムアクセスを使用し、FileGet関数で値を取得しました。しかし、取得後に続くDo While Not EOF~LOOP内の 処理が実行されません。同じファイルでVB6版で使用したら問題なく実行されたのですが。 どのように対応したらよろしいのでしょうか? よろしくお願い致します。 ソース Structure TypeUkeData '(Length = 100) <VBFixedArray(7), MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> Dim b_UkeDate() As Byte '受付日 <VBFixedArray(7), MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> Dim b_UkeTime() As Byte '受付時刻 <VBFixedArray(3), MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Dim b_UkeCnt() As Byte '件数 <VBFixedArray(79), MarshalAs(UnmanagedType.ByValArray, SizeConst:=80)> Dim b_UkeNaiyo() As Byte '内容 Public Sub Initialize() ReDim b_UkeDate(7) ReDim b_UkeTime(7) ReDim b_UkeCnt(3) ReDim b_UkeNaiyo(79) End Sub End Structure Sub ReadFile Dim b_UkeData As TypeUkeData Dim i_FileNo As Short Dim i_RecNo As Short call b_UkeData.Initialize() i_FileNo = FreeFile() FileOpen(i_FileNo, "C:\UkeData.tmp", OpenMode.Random, , , 100) ' 最初のレコードを読み込む i_RecNo = 1 FileGet(i_FileNo, b_UkeData, i_RecNo) ←b_UkeDataに確かに値は入っている Do While Not EOF(i_FileNo) ←ループ内の処理に一度も入らず次のFileCloseにいってしまう CALL SubSpilit(b_UkeData) ' 次のレコードを読み込む i_RecNo = i_RecNo + 1 FileGet(i_FileNo, b_UkeData, i_RecNo) Loop FileClose(i_FileNo) End Sub
- 締切済み
- Visual Basic
- VB2005でVC6.0で作成したDLLから値を取得するには
VB6からVB2005にコンバートをしたのですがVCで作成したDLLの関数の箇所で下記エラーが出てしまいました。(VCのDLLは他で使用の為変更できず。) エラー内容 「保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。」 いろいろサイト等を調べたのですがうまくいきません。 Marshal.AllocCoTaskMem、Marshal.Copyなどを使用すればできるらしいのですが難しすぎて挫折しました。。 どなたかご教授下さい。 よろしくお願い致します。 VC側ソース(XXX.DLL) GetData( unsigned char far *pRec, //データ short int *pRecLen, //サイズ { Char cbBuf[1024]; //バッファ memset(cbBuf, ' ', 1024); //初期化 Call GetBuf(cbBuf); memcpy(pRec, cbBuf, *pRecLen); return(0) ; } VB2005のソース <StructLayout(LayoutKind.Sequential)> Structure St Dim A () As Byte Dim B () As Byte End Structure Declare Function GetData Lib "XXX.DLL" (Byref RecData As St , ByRef Reclen As Short) As Short Sub Dim TmpData As St Dim TmpLen As short =100 Dim X As Byte Dim Y As Byte Redim TmpData.A(49) Redim TmpData.B(49) Call GetData(TmpData, TmpLen) X =TmpData.A(0) Y =TmpData.B(1) ・ ・ End Sub
- 締切済み
- Visual Basic
- VB.NETにて、構造体へデータをセットするにはどうすればよいですか?
バイナリーファイルから読み込んだデータを構造体にセットするにはどのようにすればよいですか? ご教授よろしくお願いします。 ファイルサイズは構造体のサイズと同じく300byteです。 Public Structure ST1 <VBFixedString(10), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=10)> _ Public str1() As String <VBFixedString(20), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=20)> _ Public str2() As String <VBFixedString(30), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=30)> _ Public str3() As String Public Sub Initialize() ReDim str1(4) ReDim str2(4) ReDim str3(4) End Sub End Structure 処理 Private Sub btn1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn1.Click dim ST as new ST1 ST.Initialize() FileOpen(1, OpenFileDialog1.FileName, OpenMode.Binary, OpenAccess.Read, OpenShare.Default)) FileGet(1, ST) FileClose(1) End Sub ここでわからないのが、イニシャライズを行い、配列数を設定しても、ファイルから読み込んでくるバイト数は配列でないときと同じサイズ(60byte)で読み込んできてしまいます。 STをイニシャライズしても、Marshal.SizeOf(ST)の値が変わらないのが原因だと思うのですが、宣言の仕方がおかしいのでしょうか? ご教授お願いいたします。
- 締切済み
- Visual Basic
- ★変数の属性について(VB.net 2005以上)
とあるプログラムの解析を行っています。 1997年に作られた古いもので 何回もバージョンアップや改造がされているプログラムの一部です。 Public structure Localkanri <VBFixedstring(5),system.runtime.interopservices.marshalAs(system.runtime.interopservices.unmanagedtype.byvaltstr,Sizeconst:=5)> Public End_checkNo as string Public hh as string Public BB as integer End structure 上記の属性の指定されている内容の意味が知りたいのですが・・・・ VBFixedstring(5), は5バイトの固定長です。の宣言。後ろのカンマの意味は何でしょうか? カンマで区切られ MarshalASの指定にてCLRが管理しないunmanagedtype で指定されたbyvaltstr 型。 またカンマで区切られていて Sizeconst:=5 この意味はなんでしょうか? どなたかご教授ください。
- 締切済み
- Visual Basic
- PINVOKEで構造体配列をマーシャルする方法
Cで作ったdll内の関数を.NET(C#)のプログラムからPINVOKEを介して呼び出そうとしているのですが、構造体の配列を引数として渡すにはどうするべきかわかりません。データの流れる向きは、両方向 [In, Out] です。下記の方法を試してうまくいかないのですが、どこが悪いのでしょうか?下記サンプルはうまくいかないのですが、構造体の配列をメンバーに持った構造体を使ってデータを受け渡そうとしています。もしかして、IntPtrを使って自分でマーシャリングしないとできませんか? 助言いただきたく、おねがいいたします。 -- 呼び出し側 -- using System; using System.Runtime.InteropServices; using System.Text; namespace MarshalTest { [StructLayout(LayoutKind.Sequential)] class Data { private const int buffersize = 256; [MarshalAs(UnmanagedType.I4)] public int count; [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = buffersize)] public Byte[] data; public Data() { count = 0; data = new Byte[buffersize]; } } [StructLayout(LayoutKind.Sequential)] class DataBundle { private const int buffersize = 8; [MarshalAs(UnmanagedType.I4)] public int count; [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.LPStruct, SizeConst = buffersize)] public Data[] data; public DataBundle() { count = 0; data = new Data[buffersize]; for (int idx = 0; idx < buffersize; idx++) { data[idx] = new Data(); } } } class Program { [DllImport("NativeDll.dll")] private static extern void test1([Out] Data data); [DllImport("NativeDll.dll")] private static extern void test2([Out] DataBundle data); static void Main(string[] args) { #if false // これはできます。 Data data = new Data(); test1(data); System.Console.WriteLine(Encoding.ASCII.GetString(data.data, 0, data.count)); #else // これができません。 DataBundle data = new DataBundle(); test2(data); for (int idx = 0; idx < data.count; idx++) { System.Console.WriteLine(Encoding.ASCII.GetString(data.data[idx].data, 0, data.data[idx].count)); } #endif } } } -- 呼ばれ側 -- #include <Windows.h> extern "C" { #define MAX_DATA 256 #define MAX_BUNDLE 8 struct Data { int count; char data[MAX_DATA]; }; struct DataBundle { int count; Data data[MAX_BUNDLE]; }; __declspec(dllexport) void __stdcall test1(Data *data); __declspec(dllexport) void __stdcall test2(DataBundle *data); }; void __stdcall test1(Data *data) { const char *text = "osite !! goo !!"; data->count = strlen(text); strcpy(data->data, text); data->data[strlen(text)] = '\0'; } void __stdcall test2(DataBundle *data) { const char *text = "osite !! goo !!"; for (int idx = 0; idx < MAX_BUNDLE; idx++) { strcpy(data->data[idx].data, text); data->data[idx].data[strlen(text)] = '\0'; } } 以上です。
- ベストアンサー
- C・C++・C#
- VB.NET2013多次元構造体の初期化について
Visual Studio2013 VB.NETを始めたばかりです 多次元構造体の初期化で困ってました 内容的には Public Structure ST1 Public a1 As Boolean Public a2 As Integer <VBFixedArray((9), (2)), MarshalAs(UnmanagedType.ByValArray, sizeconst:=30)> _ Public a3(,) As Long Public Sub Initialize() ReDim a3(9, 2) End Sub End Structure Public ss1(0) as ST! Public Sub test() ss1.Initialize() ss1(0).a3(0,0)=0 この状態では、多次元配列は確保されなくNothingで 初期化できない、参照型であると言うのが分かり 色々と調べてみてやっと、 コピーコンストラクタを用意して複製する方法で出来るのが分かりました Public Sub New(ByVal ss As ST1) MyClass.a1 = ss.a1 MyClass.a2 = ss.a2 MyClass.a3 = DirectCast(ss.a3.Clone(), Long(,)) End Sub End Structure Public Sub test() Dim ss0 As ST1 ss0.a1 = True ss0.a2 = 1 ss0.a3 = New Longr(,) {・・・・} Dim ss1(0) As New ss0 ただa3のサイズが大きいため定義するのは大変なので Dim bb(9,2) As Long ss0.a3 = bb としても上手く初期化できるのが分かり そしてステップ実行で中を確認していると あれっと思い 「コピーコンストラクタを用意して複製」 の方法ではなく元のまま Public Sub test() Dim bb(9,2) As Long ss1.Initialize() ss1(0).a3=bb とすると、上手く初期化され ss1(0).a3(0,1) = 100 と処理できるようになりました ただ、これで本当にいいのかが分かりません よろしくお願いします
- 締切済み
- Visual Basic
- 'StructLayout' の仕様について
.NET C++の構造体のマーシャリングについて勉強中です。 構造体のマーシャリングに 'StructLayoutAttribute' を用いる場合、 [StructLayout(LayoutKind::Sequential, Pack=8)]などと記述するようですが、msdnのドキュメントから 'StructLayout' の仕様を探すことができませんでした。 'StructLayoutAttribute'クラスの仕様はあり、おそらくこれと関連しているとは思うのですが、そのメンバやメソッドに 'StructLayout' がありません。 このあたりの理解を得るためのヒントを頂けると幸いです。 宜しくお願いします。
- ベストアンサー
- C・C++・C#
- C++で作成したDLLを vb.net から動的に
C++で作成したDLLを vb.net から動的に使用する方法 <DllImport("DllNAME")> _ Private Shared Function FuncName( _ <MarshalAs(UnmanagedType.LPStr)> ByVal str1 As StringBuilder, _ <MarshalAs(UnmanagedType.LPStr)> ByVal str2 As StringBuilder ) As String End Function Sub huga() Dim result As String = FuncName( "hoge", "piyo" ) MsgBox(result) End Sub 上記方法で 静的にはリンク出来たのですが 動的にリンクする方法がわかりません ご教授ください お願いします!
- 締切済み
- Visual Basic
- 構造体のコピー
VB6ですが、構造体のコピーは正しくできるのでしょうか type a test1(0 to 5) as byte test2 as integer test3 as string end type dim b1 as a dim c1 as a b1.test = 2 c1 = b1 私はここで、c1.test2が0だった
- ベストアンサー
- Visual Basic