String変数に入っているデータを、2進数にするには?


はるはる  2006-04-21 02:52:40  No: 95153

お世話になります。
VB6.0を使用して、制御している機器から返答されている2バイトのバイナリデータを読み取りたいのが目的です。
しかし、制御に使用しているDLLの都合から、機器から返答されるデータを、一旦String型の変数に格納しなければなりません。
(DLLの中で、Unicode に変換してString型に入れてるのだと思われる。)

String型の変数に格納されている値はすでに「・」とか「†」に変わっておりそこから2バイトのバイナリデータへ戻したいのですが、どうすれば良いでしょうか?

過去ログを探させて頂いたのですが、見つけられませんでした。


ガッ  2006-04-21 03:07:32  No: 95154

2進数も10進数もn進数も、全部同じです。
そうではなく、「文字列の2進数表現」を望んでいるのならば、
2で割ったあまりを使って作ることができますよね。
サンプルはgoogleで探せばすぐに拾えるはずです。
※表現を変えるだけで解決できるとは思えませんが、解決できるのでしょうなぁ…


もげ  2006-04-21 03:33:32  No: 95155

2バイトのバイナリデータ  と  2進数  ではちょっと意味が違うような(^^;?
> DLLの中で、Unicode に変換してString型に入れてる
の時点で文字化けが発生する恐れがあります。
(Unicodeにマップされないバイナリコードは何処へ?)
機器制御のバイナリコードをString型で渡すなんて、
悪いですけど非常識です。
一度化けたものを復元するのは容易ではないので、
DLL内でバイト配列などに格納して、
バイナリのまま受け渡すか、
String型で安全に受け取れるようHexやbase64などでエンコードして渡す
等するのが現実的ではないかと思われます。


Blue  2006-04-21 04:59:56  No: 95156

Declare宣言でStringで受け取らないようにすれば
コード変換はおこらないようにはできます。

それには、どんなインタフェースかわからないといけませんが、、、


はるはる  2006-04-21 05:16:43  No: 95157

御返答ありがとうございます。

>2バイトのバイナリデータ  と  2進数  ではちょっと意味が違うような

最終的にはバイナリデータが
2バイト単位で2の補数表現されてるそうなので、そのデータを10進数に戻してデータを取り込みたいんです。
なんで、まずバイナリデータにしなければならないんですが…

>機器制御のバイナリコードをString型で渡すなんて、
>悪いですけど非常識です。
>一度化けたものを復元するのは容易ではないので、

私もそう思うんですが、機器との通信機器のメーカー作成のドライバ(
DLL)と、それと一緒についてたVB6用のモジュールでは、勝手にString型にして返り値にしているんです…(TЛT)
メーカーに相談してみます。

もし、誰か良い方法を知っていたら教えてください。


ガッ  2006-04-21 08:08:23  No: 95158

/*
(やっぱり)よくわかりませんねー

> 最終的にはバイナリデータが
> 2バイト単位で2の補数表現されてるそうなので、
> そのデータを10進数に戻してデータを取り込みたいんです。
Integer型ということですねー

> なんで、まずバイナリデータにしなければならないんですが…
すべてのデータはバイナリですねー…

> >機器制御のバイナリコードをString型で渡すなんて、
> >悪いですけど非常識です。
> >一度化けたものを復元するのは容易ではないので、
> 私もそう思うんですが、機器との通信機器のメーカー作成のドライバ(DLL)と、
> それと一緒についてたVB6用のモジュールでは、勝手にString型にして返り値にしているんです…(TЛT)
一緒についているVB6用のモジュールの役目がよくわかりませんねー
まぁ、仕方なしに使っているのだと思いますがー
(使わなければいいのでは、というのはナッスィングな答えでしょうかね?)

VB6のString型は(他の方も書いていらっしゃる様に)いろいろなところで内部表現のUnicodeとShift-JIS(?)とで相互変換される可能性があります
(つまり、"もしかしたら"変換されていないかもしれない、ということです)

VB6ではByte()⇔Stringができますので、まずはByte()として受け取り、
さらにWinAPIのRtlMoveMemory(またはCopyMemory)でInteger()にコピーして、
それを読み取るようにすれば"できるかも"しれませんねー

まー、できるかどうかは色々な意味で保障できませんがー
*/

以上


K.J.K.  2006-04-21 08:49:55  No: 95159

付属していたVB6用のモジュール、というのは、標準モジュール(*.bas)
か何かで、Declareステートメントを使って関数を宣言している、という
ことでしょうか? もしそうであるのならば、書き直すことでByte型
(の配列)を受け取るようにできません?


はるはる  2006-04-21 21:30:27  No: 95160

御返答、ありがとうございます。

>付属していたVB6用のモジュール、というのは、標準モジュール(*.bas)
>か何かで、Declareステートメントを使って関数を宣言している、という
>ことでしょうか? 

そうなります。
CALLで標準モジュールの中の関数を呼び出し、結果を取得しております。
しかし、標準モジュールの関数がさらにDLLファイルを呼び出しており、その戻り値からString型になっているので、手がつけられません。

>VB6ではByte()⇔Stringができますので、まずはByte()として受け取り、
>さらにWinAPIのRtlMoveMemory(またはCopyMemory)でInteger()にコピーして、
>それを読み取るようにすれば"できるかも"しれませんねー

ありがとうございます。
Byte関数でなんとかなりそうです。
計測器の表示と確認中です。
ありがとうございます。

>(使わなければいいのでは、というのはナッスィングな答えでしょうかね?)
すみません、ほかの方法が分からないので…


K.J.K.  2006-04-21 22:57:32  No: 95161

> しかし、標準モジュールの関数がさらにDLLファイルを呼び出しており、
> その戻り値からString型になっているので、手がつけられません。

いや、手をつけられるでしょう。
元の関数のCでの表記を調べて、そこから直に書き下してみては。


Say  2006-04-23 21:16:12  No: 95162

K.J.K.さんの発言を解説すると、
VBのDeclare宣言で「As String」になっているのは、
手っ取り早くアドレス経由でデータをわたす手段として用いているというだけで、
Cのプロトタイプではおそらくポインタ型になっているはず、ということです。

おそらく、この種のAPIは、
[1]呼び出し側でバッファを用意して、その先頭アドレスを渡すと、データを入れて返す。
[2]API内部にバッファを持っており、関数の戻り値としてそのアドレスを返す。
のどっちかの可能性が高いと思うのですが・・・
(「その戻り値からString型になっているので」ということなら、
後者の可能性大ですが・・・)

[1]ならバイト配列用意して、その先頭アドレスを渡せばよいし、
[2]なら、アドレスを受け取った後、RTlMoveMemoryあたりで
バイト配列にコピーすればよいはずです。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加