- - PR -
データ型の変換方法について(BYTE型⇒????)
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2005-09-01 14:37
こんにちは。VB.NETの初心者です。
今、アンマネージコード(C++)⇔マネージコード(VB.NET)の 連携をしています。 その中でIN(値渡し)で指定した値によって、1つの変数へ 複数の種類をもったデータが返却(OUT)されてしまう為、 求めているデータを取得できずに困っています。 どなたか良い方法がありましたら、教えてください。 具体的には、属性の異なるデータが、全てchar[]のデータ型で 返却されてしまう為、BYTE型であれば取得できるが、その後の 変換ができない。 その為、BYTE型からの変換方法や他の取得方法があれば教えて ほしいという事です。 詳細情報は以下の通りです。 【開発言語】 VisualBasic2005 【DLLインターフェース】 TEST_RESULT TEST_APICALL COLUMN_DATA_GET( //IN :カラムID(DBにおける項目のID) int ColumnID, //OUT :INで指定したカラムIDの列に格納された全てのデータ // ※複数の種類をもったデータが返却(OUT)されてしまう。 char[100] DataBuf ); 【"DataBuf"へ返却されるデータの種類】 @整数データ(4Byte) 例:格納データ:1,2・・・の場合 ⇒BYTE配列で取得すると[1][0][0][0],[2][0][0][0]・・・と返却される。 A浮動小数点データ(8Byte) 例:格納データ:1.000,2.000・・・の場合 ⇒BYTE配列で取得すると[0][0][0][0][0][0][240][63],[0][0][0][0][0][0][0][64]・・・と返却される。 B日付けデータ(8Byte) 例:格納データ:2005/01/01,2005/02/01・・・の場合 ⇒BYTE配列で取得すると[0][0][0][0][32][186][226][64],[0][0][0][0][0][190][226][64]・・・と返却される。 C時刻データ(8Byte) 例:格納データ:1:00:00,2:00:00・・・の場合 ⇒BYTE配列で取得すると[85][85][85][85][85][85][165][63],[85][85][85][85][85][85][181][63]・・・と返却される。 D日付け時刻データ(8Byte) 例:格納データ:2005/01/01 01:00:00,2005/02/01 01:00:00・・・の場合 ⇒BYTE配列で取得すると[85][85][85][85][33][186][226][64],[85][85][85][85][1][190][226][64]・・・と返却される。 【データの格納イメージ】 ⇒左から順に、カラムIDが1,2,3,4,5,6となる。 整数データ,浮動小数点データ,日付けデータ,時刻データ,日付け時刻データ 1 ,1.000 ,2005/01/01 ,01:00:00 ,2005/01/01 01:00:00 2 ,2.000 ,2005/02/01 ,02:00:00 ,2005/02/01 02:00:00 ・ ・ ・ 【作成中のプログラムコード】 Public Declare Function DATA_GET Lib "test.dll" ( _ ByVal ColumnID As Integer, _ ByVal DataBuf() As Byte, _ ) As Integer Public Sub TEST() As Integer Dim i,ColumnID As Integer = 1 Dim DataBuf(100) As Byte For i = 0 to 100 - 1 Debug.print(DataBuf(i)) Next End Sub | ||||
|
投稿日時: 2005-09-01 15:36
試していませんが、BitConverterとかは使えないですかね?
日付は辛そうですが。。。 | ||||
|
投稿日時: 2005-09-01 15:39
諸農です。
カラム位置というか、変換の対象にするバイト配列を取得できるのであれば、 BitConverterの各メソッドが使えると思いますが。 _________________ 諸農和岳 Powered by Turbo Delphi & Microsoft Visual Studio 2005 十兵衛@わんくま同盟 http://blogs.wankuma.com/jubei/ | ||||
|
投稿日時: 2005-09-01 16:05
BitConverter を使うとオフセットの管理が面倒じゃないですか? ・byte 型の配列として結果を受け取る ・byte 型の配列から MemoryStream を作る ・BinaryReader で MemoryStream から必要な情報を読み出す のが簡単と思います。 _________________ // 渋木宏明 (Hiroaki SHIBUKI) // http://hidori.jp/ // Microsoft MVP for Visual C# // // @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/ | ||||
|
投稿日時: 2005-09-01 19:22
burton999さん、Jubeiさん、渋木宏明(ひどり)さん
返答ありがとうございます。 何だか難しそうなクラスで、まだよくわかっていないので、"BitConverter","MemoryStream"の方法を両方試してみます。 | ||||
|
投稿日時: 2005-09-01 21:42
早速、"BitConverter"と"MemoryStream"を
試してみました。 しかし、"BitConverter"はうまく取得できましたが "MemoryStream"を使用した場合はエラーが発生して しまい、原因 or 使用方法がよくわかりません。 もし、よろしければアドバイス頂けないでしょうか? 【整数データを取得した場合のプログラムコード】 @"BitConverter"の場合 正常に1,2,3,4,5・・・とデータが取得できた。 Public Declare Function DATA_GET Lib "test.dll" ( _ ByVal ColumnID As Integer, _ ByVal DataBuf() As Byte, _ ) As Integer Public Sub TEST() As Integer Dim i,ColumnID As Integer = 1 Dim DataBuf(100) As Byte For i = 0 to 100 - 1 Debug.print(BitConverter.ToInt32(Databuf, i)) i += 3 Next End Sub A"MemoryStream"の場合 データが取得できない。 「EndOfStreamException」が発生する。 <エラー内容> System.IO.EndOfStreamException はハンドルされませんでした。 Message="ストリームの終わりを超えて読み取ることはできません。" Source="mscorlib" StackTrace: 場所 System.IO.__Error.EndOfFile() 場所 System.IO.MemoryStream.InternalReadInt32() 場所 System.IO.BinaryReader.ReadInt32() 場所 test.TEST_Form.Button3_Click(Object sender, EventArgs e) 場所 C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Projects\TEST\test\TEST_Form.vb:行 136 場所 System.Windows.Forms.Control.OnClick(EventArgs e) 場所 System.Windows.Forms.Button.OnClick(EventArgs e) 場所 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) 場所 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 場所 System.Windows.Forms.Control.WndProc(Message& m) 場所 System.Windows.Forms.ButtonBase.WndProc(Message& m) 場所 System.Windows.Forms.Button.WndProc(Message& m) 場所 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 場所 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 場所 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 場所 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 場所 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData) 場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 場所 System.Windows.Forms.Application.Run(Form mainForm) 場所 test.TEST_Form.Main() 場所 C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Projects\TEST\test\TEST_Form.Designer.vb:行 2 場所 System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args) 場所 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 場所 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 場所 System.Threading.ThreadHelper.ThreadStart_Context(Object state) 場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 場所 System.Threading.ThreadHelper.ThreadStart() <プログラムコード> Public Declare Function DATA_GET Lib "test.dll" ( _ ByVal ColumnID As Integer, _ ByVal DataBuf() As Byte, _ ) As Integer Public Sub TEST() As Integer Dim i,ColumnID As Integer = 1 Dim DataBuf(100) As Byte Dim ms As New System.IO.MemoryStream() ms.Write(Databuf, 0, Databuf.Length) Dim br As New System.IO.BinaryReader(ms) For i = 0 to {データの件数-1} Debug.print(br.ReadInt32()) Next End Sub [ メッセージ編集済み 編集者: taa 編集日時 2005-09-01 21:43 ] [ メッセージ編集済み 編集者: taa 編集日時 2005-09-01 21:44 ] | ||||
|
投稿日時: 2005-09-01 22:44
ストリームに書き込んでいくと、Positionは当然書き込んでいるところを指します。 で、位置を変更しないままReadしてしまうと最後尾から読もうとしてEOFに突き当たってしまうわけです。 書き込みが終わったらPositionを一旦0に戻してあげて下さい。 | ||||
|
投稿日時: 2005-09-02 10:36
Hongliangさん返答ありがとうございます。
以下(★)の記述をすることで正常に動作しました。 これで、整数型は取得できそうです。 ただし、他の型についてはマネージコード側(VB.NET)に うまくあてはまる型がなさそうなので、"Format メソッド"等 を使用して正常にデータを表示できないものかと模索しています。 もし、こちらもうまい方法があれば、URLでもなんでも良いので 情報頂ければと思います。 後、BYTE型からの変換以外の方法は、無いものでしょうか? マーシャラーが使用できればと思っていますが、マネージコード側で 取得する型が一定でないので無理そうでした。 こちらも、こちらもうまい方法があれば、URLでもなんでも良いので 情報頂ければと思います。 <プログラムコード> Public Declare Function DATA_GET Lib "test.dll" ( _ ByVal ColumnID As Integer, _ ByVal DataBuf() As Byte, _ ) As Integer Public Sub TEST() As Integer Dim i,ColumnID As Integer = 1 Dim DataBuf(100) As Byte Dim ms As New System.IO.MemoryStream() ms.Write(Databuf, 0, Databuf.Length) ★ms.position = 0 Dim br As New System.IO.BinaryReader(ms) For i = 0 to {データの件数-1} Debug.print(br.ReadInt32()) Next End Sub |
1