- PR -

データ型の変換方法について(BYTE型⇒????)

1
投稿者投稿内容
taa
常連さん
会議室デビュー日: 2005/08/29
投稿数: 44
投稿日時: 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
burton999
ぬし
会議室デビュー日: 2003/10/06
投稿数: 898
お住まい・勤務地: 東京
投稿日時: 2005-09-01 15:36
試していませんが、BitConverterとかは使えないですかね?
日付は辛そうですが。。。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2005-09-01 15:39
諸農です。

カラム位置というか、変換の対象にするバイト配列を取得できるのであれば、
BitConverterの各メソッドが使えると思いますが。


_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2005-09-01 16:05
引用:

その中でIN(値渡し)で指定した値によって、1つの変数へ
複数の種類をもったデータが返却(OUT)されてしまう為、
求めているデータを取得できずに困っています。



BitConverter を使うとオフセットの管理が面倒じゃないですか?

・byte 型の配列として結果を受け取る
・byte 型の配列から MemoryStream を作る
・BinaryReader で MemoryStream から必要な情報を読み出す

のが簡単と思います。

_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#
//
// @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/
taa
常連さん
会議室デビュー日: 2005/08/29
投稿数: 44
投稿日時: 2005-09-01 19:22
burton999さん、Jubeiさん、渋木宏明(ひどり)さん
返答ありがとうございます。
何だか難しそうなクラスで、まだよくわかっていないので、"BitConverter","MemoryStream"の方法を両方試してみます。
taa
常連さん
会議室デビュー日: 2005/08/29
投稿数: 44
投稿日時: 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 ]
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2005-09-01 22:44
引用:

taaさんの書き込み (2005-09-01 21:42) より:
"MemoryStream"を使用した場合はエラーが発生して
しまい、原因 or 使用方法がよくわかりません。


ストリームに書き込んでいくと、Positionは当然書き込んでいるところを指します。
で、位置を変更しないままReadしてしまうと最後尾から読もうとしてEOFに突き当たってしまうわけです。
書き込みが終わったらPositionを一旦0に戻してあげて下さい。
taa
常連さん
会議室デビュー日: 2005/08/29
投稿数: 44
投稿日時: 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

スキルアップ/キャリアアップ(JOB@IT)