• 締切済み

VB6からVCで作成したDLLへのvoidポインタの受け渡し

VB6でVCで作成されたDLLの関数から戻り値としてvoidポインタを受け取り、 それをDLLの別の関数を呼び出す際に引数として渡すプログラムを作成しようとして 詰まっています。以下サンプルです。 ===VB側 Public Type Param   sStr As String   lNum As Long End Type Declare Function Create Lib "test.dll" (ByRef tParam As Param) As Long Declare Function Free Lib "test.dll" (ByVal pSt As Any) As Long Dim pSt As Long Dim lRet As Long Dim tParam As Param With tParam   .sStr = "test" & Chr(0)   .lNum = 10 End With pSt = Conn(tParam) lRet = Free(pSt) ===VC側 typedef struct stParaA {   char * aaa;   char * bbb; } PARAM_A; typedef struct stParaB {   char * ccc;   int iNum; } PARAM_B; extern "C" void * __stdcall Create(PARAM_B* stParaB) {   PARAM_A stParaA;   //stParaAの各メンバ領域をMallocで確保   return((void*)stParaA); } extern "C" int __stdcall Free(void* stParaA) {   //stParaAの各メンバ領域をfree   return 0; //正常終了の場合 } VC側でデバッグしてみたところ、stParaBの各メンバの値はVC側で取得できているので、 DLLの呼び出し自体には問題はないようですが、Create()でreturnする時と、Free()に 入ってきたときではstParaAのアドレスが変わってしまい、異常終了します。 VC側はソースはあるのでデバッグは可能なのですが、DLLの修正自体は不可となって いるため、VB側を直すしかないのですが、どのようにすればアドレスの受け渡しが できるのでしょうか。

みんなの回答

  • dsuekichi
  • ベストアンサー率64% (171/265)
回答No.1

気になったところを2つほど・・・ (1)「Free 」の宣言で「ByVal pSt As Any」としてますが、 「ByVal pSt As Long」の方が良いのでは? (2)「DLLの修正自体は不可」との事ですが・・・ C側の「PARAM_A stParaA;」って、ローカル変数ですよね・・・ 私の認識では、ローカル関数は関数が終了すると、解放されてしまう・・・ #Mallocした領域は残りますが、Mallocした領域がどこかを記録している、 #stParaAは解放されてしまって、別の用途に使われてしまうかも。 もし正しいアドレスが渡されたとしても、コレでは駄目(でたらめな値になっていて、異常終了する)なのでは?

mamaremon
質問者

補足

>C側の「PARAM_A stParaA;」って、ローカル変数ですよね・・・ >私の認識では、ローカル関数は関数が終了すると、解放されてしまう・・・ えっと、stParaAは変数ですが、(void*)stParaAは変数ではなく、ポインタであるというのは分かりますでしょうか。変数≠ポインタです。変数を渡したいわけではなく、Mallocで確保した領域のアドレスそのもの(ポインタ)を渡そうとしているのが、サンプルコードなのですが、ご理解いただけますでしょうか。ポインタというのはメモリ上のアドレス(位置情報)のことなので、そのメモリの領域が解放されようとも、ポインタそのものがなくなることはありません。 結論からいうと、私の意図した動作はサンプルコードで動くようです。お騒がせしました。異常終了したのはまた別の要因でしたが、割愛させていただきます。