2015年5月29日金曜日

Variant型引数をもつDLLの呼出(VisualStudio2013)


今回の仕事も古いDLLを使用して相手装置のログを読み出す開発。

DLLの説明書にはVB6.0での使用方法しか書かれていない。
発注元からVisualStudio2013から呼び出せるのか確認してもらうと
実際に確認していないが動作するはずですとの回答。
なんとかなるよなと。。。


正直、私が使ったことがあるのVisualStudio6.0で以降の開発環境って今回が初めて。
ここ数年Javaがメインで開発しているしMicrosoft製品っていうかDLLとかよく判らない。
動的なライブラリってのはわかってますが。



OS     Windows7 Pro 32Bit版
開発環境 Visual Basic 2013

簡単にやりたいことを書き出すとアナログ値を収集する装置から
一定間隔で値を取得しDBへ保存する。
収集装置から値を取り出すのにDLLを使用する。


DLLをどうやって使うのかも微妙な感じで社内のMicrosoft製品での開発に詳しい人に聞いて何とかDLLをソースで呼び出せるようになる。

さて実行して見ると実機を前にDLL側から提供されているInit()、Open()は問題なく呼び出せた。
で、実際に値を読み取るメソッドでエラーとなってしまう。

このメソッドの引数が
Method(String , String, variant)

ソースはこんな感じ

Imports VS6Lib
class test(){
Private vs6Lib As VS6Lib.VS6COMM
sub test() {
Dim ret As Long
Dim ret As Object = new Object
vs6Lib = new VS6Lib.VS6COMM()
'' DLL初期化
ret = vs6Lib.init()
IF ret<>0 THEN
'' エラー処理
ENDIF
'' 装置へ接続
ret = vs6Lib.open()
IF ret<>0 THEN
'' エラー処理
ENDIF
'' アナログ値読み出し
ret = vs6Lib.Method("装置名","ALL_READ", obj)
IF ret<>0 THEN
'' エラー処理
ENDIF
~DB登録等の処理~
}
}

variant型はObject型に置き換えるとの記載を目にしたのでvariantの引数はObjectを
渡しているのだがDLLから帰ってくるエラー内容は、データ配列数が少ないとなっている。

このメソッドを使用するとvariant型に取得したいアナログ値をByte配列にして
戻してくれるらしいのだが…

同じ動作をするメソッドでvariantの箇所をStringでファイル名を指定するとファイルに出力してくれるメソッドがあるのでこちらを試してみると正常終了となりファイルも作成されてて当然値も出力されている。

やっぱりvariant型への引数の渡し方が悪いんだね。

調べてみても有用な情報は見つからず…
既に値が取れる前提で以降の処理は作成されているため変更は手戻りが大きすぎる。

なんとか引数を渡せないのか?
DLLからはByte配列が戻ってくるのでByte配列を引数に指定してみるが型が違うとエラーになる。当然か…

やっぱりファイル経由で値を取らないと駄目なのか?

しばし、考察


variant型の使い方を見ているとユーザ定義型などをvariant型引数に突っ込んだり出来るらしい。
もしかしてObject型にもユーザ定義型って突っ込めるのか?

そう思い試してみることに

'' Byte配列を定義
Dim b(0 To 64) As Byte
obj = b
'' アナログ値読み出し
ret = vs6Lib.method("装置名","ALL_READ", obj)
IF ret<>0 THEN
'' エラー処理
ENDIF

こんな感じで試してみるとエラーは発生しないで値を取れました!

取れたんですがさらに厄介なことに
 byte, byte,       byte, byte, byte, byte
 状態, ステータス, 値(Single 4byte)
ってな状態で返してくれているらしい。浮動小数点byteの中見ても判らんし正しい値が取れているのか?

Singleは浮動小数点なのでbyteを単純に変換出来るのか?
と調べてみると
System.BitConverter.ToSingle(byte配列, 開始位置)
Byte配列からシングルへの変換メソッドが有りました

        Dim sVal as Single = System.BitConverter.ToSingle(b, 2)

こんな便利なメソッドが用意されているなんて素敵です。
これで無事値を取得することが出来ました。


しかしVBって結構沢山の人が使っていると思うのだが情報を見つけるのが大変。
検索の仕方が悪いのか目的の情報になかなかたどり着けない。
情報が多すぎるんだろうなきっと。。。


この装置が出来てから10年近く立ってるんだったらDLL位更新して欲しいよな。後64bit版もね
ハード屋さんなんでソフトを再作成するの面倒なのかな?

0 件のコメント:

コメントを投稿