DOBON.NET どぼん!のVB道掲示板(プログラム)過去ログ

オブジェクトのアドレス

検索しても引っかからなかったためご教授願いたいのですが。

VB6においてオブジェクトのアドレスを取得したい場合には
どのようにすればよいのでしょうか?
外部DLLなどに構造体内部にあるLong項目にByte配列のオブジェクトの
アドレスを渡したいのですが。

例えば
Type test
aa As Integer
bb As Long
End Type

Dim dat(32) As Byte

で、test の bb に dat ( dat(0) ) のアドレスを設定したいのですが。

すみませんが、よろしくお願い致します。
>検索しても引っかからなかったためご教授願いたいのですが。
>
>VB6においてオブジェクトのアドレスを取得したい場合には
>どのようにすればよいのでしょうか?
>外部DLLなどに構造体内部にあるLong項目にByte配列のオブジェクトの
>アドレスを渡したいのですが。
>
>例えば
>Type test
> aa As Integer
> bb As Long
>End Type
>
>Dim dat(32) As Byte
>
>で、test の bb に dat ( dat(0) ) のアドレスを設定したいのですが。
>
>すみませんが、よろしくお願い致します。

ほほぅ・・・私より凄いことを考えている方が居られるとは、、、。
実を云うと、VB6以前のVBの最大の制約は

・関数のポインタはAddressOfで渡せても、変数のポインタは渡せない

ということです。
Windows APIの中にもこの形式のインターフェースを持ったものが幾つかあります。それらAPIは、つまり、VBからは利用できない??、、、

ところが、私はある方法でそれを可能にしましたがね。
後で説明しましょう。
次回、乞うご期待・・・
>実を云うと、VB6以前のVBの最大の制約は
>・関数のポインタはAddressOfで渡せても、変数のポインタは渡せない
>ということです。
AddressOfも最近実装されたようですね??
その辺りから調べて回ったのですが何も見つからなくて困っています。

>ところが、私はある方法でそれを可能にしましたがね。
>後で説明しましょう。次回、乞うご期待・・・
よろしくお願いします。
楽しみに・・・おとなしく・・・一旦調査を休憩して待っています(^^;
>>実を云うと、VB6以前のVBの最大の制約は
>>・関数のポインタはAddressOfで渡せても、変数のポインタは渡せない
>>ということです。
>AddressOfも最近実装されたようですね??
>その辺りから調べて回ったのですが何も見つからなくて困っています。
>
>>ところが、私はある方法でそれを可能にしましたがね。
>>後で説明しましょう。次回、乞うご期待・・・
>よろしくお願いします。
>楽しみに・・・おとなしく・・・一旦調査を休憩して待っています(^^;

後編です。
ところで、期待しているところ申し訳ありませんが、ひとつ確認したことがあります。
呼出したいと言っているDLLは、カスタムメードのDLLのようですが、そっちを修正して、タグ/Typeを引数で渡す、ましてや、そのタグのメンバの中にポインタをセットしなければならないものがあるというようなインタフェースを変えられないものなのでしょうか?
もし、自前で開発しているのであれば、それが一番いいのですが。というのは、ByRef引数は勝手に「ポインタ渡し」になるので、タグのメンバを個別に引数で渡す形に変更すれば、それが最善の解決策になります。

これに対し、私の編み出した苦肉の策は、
・GlobalAlloc/GlobalLock/GlobalUnlock/GlobalFree
・CopyMemory
という沢山のAPIを使用する複雑な方法です。

要領はこういうことです。
GlobalAlloc/GlobalLockで取得したメモリのアドレスは、VB側ではLongの戻り値として受取れます。そして、CopyMemoryを使って、Byte配列のデータをそこへコピーします。そうすれば、そのLong値をタグにセットすることで、Byte配列のポインタを渡したのと同じ効果が得られるというわけです。そして、結果としてそのメモリ領域にデータがセットされて返ってきたなら、今度は逆向きにCopyMemoryすることで、Byte配列に情報を受取ることも可能です。

ただし、APIビューアが用意している、CopyMemory APIの引数のままでは、型が合わないのでコンパイルを通せません。そこで、Aliasを使って、自分が必要としている型の引数に変更した、CopyMemoryエイリアスを幾つか用意して、時と場合に応じてそれらを使い分けるわけです。

それから、GlobalAlloc/GlobalLockしたハンドルは、必ず使い終わったらGlobalUnlock/GlobalFreeすることも忘れてはなりません。

大雑把ですが、こんな感じで処理すれば何とかなります。
回答ありがとうございます。

>呼出したいと言っているDLLは、カスタムメードのDLLのようですが、そっちを修正して、タグ/Typeを引数で渡す、ましてや、
>そのタグのメンバの中にポインタをセットしなければならないものがあるというようなインタフェースを変えられないものなのでしょうか?
>もし、自前で開発しているのであれば、それが一番いいのですが。というのは、ByRef引数は勝手に「ポインタ渡し」になるので、
>タグのメンバを個別に引数で渡す形に変更すれば、それが最善の解決策になります。

残念ながら自前のものではないため上記方法で解決することが出来ないのです。

>これに対し、私の編み出した苦肉の策は、
>・GlobalAlloc/GlobalLock/GlobalUnlock/GlobalFree
>・CopyMemory
(略)
>大雑把ですが、こんな感じで処理すれば何とかなります。

なるほど!
APIビューアーを眺めながら確認をしているところです。
ありがとうございました。もう一度探してみて良い手がないようであれば
この方法で実現しようと思います。
本当にありがとうございました。
>回答ありがとうございます。
>
>>呼出したいと言っているDLLは、カスタムメードのDLLのようですが、そっちを修正して、タグ/Typeを引数で渡す、ましてや、
>>そのタグのメンバの中にポインタをセットしなければならないものがあるというようなインタフェースを変えられないものなのでしょうか?
>>もし、自前で開発しているのであれば、それが一番いいのですが。というのは、ByRef引数は勝手に「ポインタ渡し」になるので、
>>タグのメンバを個別に引数で渡す形に変更すれば、それが最善の解決策になります。
>
>残念ながら自前のものではないため上記方法で解決することが出来ないのです。
>
>>これに対し、私の編み出した苦肉の策は、
>>・GlobalAlloc/GlobalLock/GlobalUnlock/GlobalFree
>>・CopyMemory
>(略)
>>大雑把ですが、こんな感じで処理すれば何とかなります。
>
>なるほど!
>APIビューアーを眺めながら確認をしているところです。
>ありがとうございました。もう一度探してみて良い手がないようであれば
>この方法で実現しようと思います。
>本当にありがとうございました。

偶然ですが、凄いものを発見してしまいました。

http://msdn.microsoft.com/library/en-us/dnvb600/html/vb6tovbdotnet.asp

このページの Avoid Legacy Features というところをクリックしてみてください。
VB6.0なら、VarPtr, ObjPtr, StrPtrなどという「ドキュメントにない」演算子を使うと、変数のアドレスを得られるそうです。.NETでは完全に無くしたそうですが、こんな隠し機能を使っていた人も実際にいるのかなぁ??

DOBON.NET | プログラミング道 | プログラミング掲示板