• ベストアンサー

VCのDLL内でmallocした構造体をVBで使用

題名通りですが、 VC側のDLLにてmallocで構造体の領域を確保しています。 この領域をVB側で使用したいのですが、やり方がわかりません。 イメージは Public Declare Function GetData Lib "xxx.dll" (ByRef datas As KOUZOUTAI, ByRef dataCnt As Long) As Boolean みたいな形で、datasに構造体のデータ、及び dataCntに領域確保したデータ数を取得出来ればなと思っております。 VB側では、これもイメージですが、 dim datas() as KOUZOUTAI dim dataCnt as long GetData(datas, dataCnt) for cnt=0 to dataCnt - 1 msgbox datas(cnt).a msgbox datas(cnt).b msgbox datas(cnt).c next みたいな感じで処理をしたいと思っております。 お聞きしたい事は 1)そもそも可能なのか? 2)declare宣言のdatasのところが???です。 3)dim datas() as KOUZOUTAIのところも宣言が???です。 4)datas(cnt).a等としているところも配列?として処理出来るのかが???です。 以上、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.3

>1)そもそも可能なのか? VC側でVB配列を扱える人が作ったDLLなんでしょうか? できるようならmallocは使わずSafeArray系APIを使うと思います。 最低でもVB側で解放できるようにGlobalAllocを使うはずです。 無理すれば可能だとは思いますが、一時的に成功してもガベージ コレクションが起きた後で動作が不安定になるでしょう。 >2)declare宣言のdatasのところが???です。 VC側で SAFEARRAY **datas となっていれば datas() As KOUZOUTAIと なります。そうすると、mallocではなく、SafeArrayCreateで確保 された領域のポインタが入らなくてはなりません。 VC側が struct xxx *p となっているならdatas As KOUZOUTAIです。 >3)dim datas() as KOUZOUTAIのところも宣言が???です。 Declarationの所では配列要素数を省略した定義は可能です。 後でReDim文で配列領域を確保します。配列要素数を定義すると 固定配列になるので、VC側でメモリを削除したり、確保したり できません。 >4)datas(cnt).a等としているところも配列?として処理出来るのかが???です。 構造体の配列は使用可能です。書式も合っています。 どうしてもVC側で作ったものを使いたいならGlobalAllocでメモリを 確保し、これを戻り値(Long型)とします。VB側では必要な領域を 確保した後、RtlMoveMemoryで内容をコピーして使えば良いでしょう。 尚、VBの変数のポインタはVarPtr関数で求められます。

Vargas
質問者

補足

詳細な回答ありがとうございます。 3)がちょっと気になります。 dim datas() as KOUZOUTAI という宣言がOKなのはわかるのですが、 このあと、redimをしなければならないというところが引っ掛かります。 VC側でHeapAllocでメモリ確保しているのですが、その先頭ポインタ(この考えはVBには無いとは思いますが。)をVB側で受け取っているのに、更に、redimしなければならないのでしょうか? もしかしたら、VB側ではRtlMoveMemoryで上記redimした領域にコピーを行った上で使用しなければならないという意味でしょうか? であれば納得です。 以上、再度、ご回答頂けると幸いです。

その他の回答 (3)

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.4

VBの配列は複雑な管理になっており、先頭ポインタに構造体サイズを 加えれば次の要素のポインタになると言うものではありません。 先ず、管理情報として定義済み(Eraseされていない)フラグが あります。ReDimしていないとこれがFalseですし、LBound、Uboundの 定義も未設定になっています。当然、データ用の領域もありません。 VC側のHeapAllocで取得した領域に上記のような管理情報とデータを 仕込み、更にVB側のメモリ管理に登録する方法をご存知ならば、 何も申し上げることはございません。ReDimするしないも自由です。

Vargas
質問者

お礼

3度にわたるご回答、大変感謝しております。 VB6はそれなりにやってきたつもりでしたが、 今回は全く知らなかった事ばかりで知識が増えました。 ありがとうございました。

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.2

VBはVB6.0(VBA含む)とVB.NET以降では全く別物です。 どちらのバージョンを使用するのか記載しないと適切なアドバイスは 受けられません。使用する環境を記載してください。

Vargas
質問者

補足

すいません。ソースイメージを記述したので、自ずとVB.NETではないと捉えてくれるかなと思いました。VB6.0です。よろしくお願いします。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

その構造体の内容(メンバー)を提示しましょう たとえば struct tagData{   int a;   short b;   byte c; }; といった構造体なら VB6以前であれば Type tagData   dim a as Long   dim b as Integer   dim c as Byte End type といった具合になります 構造体の配列となると SafeArrayタイプでC++側でデータを構築しないとうまくわたらなかったりしますよ VC付属のMSDNで Visual Basic 5.0 から呼び出し可能な DLL の作成例 取った題目のサポート技術を参照してみましょう

参考URL:
http://support.microsoft.com/kb/410837/ja
Vargas
質問者

お礼

この記事は大変助かりました。ありがとうございました。

Vargas
質問者

補足

このURL大変参考になりました。ありがとうございます。 ところで、当方の環境はVB6なのですが、VB6用のこの様な記事が見当たりません。VB5と同じと考えていいんですよね。

関連するQ&A