DLLからVBの関数を呼びたいと思い、サンプルを作ってみたのですが、
実行後、VBがダウンします。
原因が分かる方は、ご教授お願いします。
<VBのソース>
Private Declare Function RetStr Lib "CallBack.dll" (ByVal VB_Func As Long) As Long
Private Declare Function MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As String, ByVal Source As Long, ByVal Length As Long) As Long
Public Sub Main()
Call RetStr(AddressOf Func)
End Sub
Public Function Func(ByVal p As Long, ByVal Length As Long) As Long
Dim tmp As String
tmp = String$(Length, vbNullChar)
Call MoveMemory(tmp, p, Length)
Debug.Print tmp
End Function
<DLLのソース>
#include <windows.h>
void __stdcall CALLBACK RetStr(int *VB_Func);
void __stdcall CALLBACK RetStr(int *VB_Func)
{
int (*Func)(long, int);
char *str = "ABCDEFG";
Func = (int(*)(long, int))VB_Func;
Func((long)str, 8);
}
一応、デバッグウィンドウで値は見れます。
("ABCDEFG"が表示されます)
よろしくお願いします。
なんとなく
> int (*Func)(long, int);
"long"で大丈夫ですか?
>void __stdcall CALLBACK RetStr(int *VB_Func);
__stdcallを着けるならCALLBACKは不要。
(CALLBACKは__stdcallの#define)
というか意味合い的に、CALLBACK関数はFuncでしょう。
また、DLLの型はVBの型にあわせなくてもいい気がしますけど。
>Private Declare Function RetStr Lib "CallBack.dll" (ByVal VB_Func As Long) As Long
void型の関数なのに戻り値を欲している。
Private Declare Subです。
それと
>Public Function Func(ByVal p As Long, ByVal Length As Long) As Long
値を返さないならSubで。
上を直してもまだおちるっぽい。
(コメントアウトすれば動くところから)
DLLからVBの関数を呼ぶところをがだめなようです。
わかった。
DLL側でVBから受けた関数ポインタをキャストするときに
__stdcallがついていないため、呼び出し方が不正になり終了時に
メモリの参照位置がずれちゃうとかそういうことなんでしょう。
よって、まとめると
void WINAPI RetStr(void (CALLBACK *VB_Func)(char*, int))
{
char* str = "ABCDEFG";
VB_Func(str, 8);
}
として、
Private Declare Sub RetStr Lib "CallBack.dll" (ByVal VB_Func As Long)
とすれば動くはず。
書き忘れ
>Public Function Func(ByVal p As Long, ByVal Length As Long) As Long
void (CALLBACK *VB_Func)(char*, int)
としたので
Public Sub Func(ByVal p As Long, ByVal Length As Long)
とします。
(もしくはDLLでint (CALLBACL *VB_Func)(char*, int))
お忙しい中、早々のご返答有難うございました。
無事解決しました。
ツイート | ![]() |