私はwin32アセンブリでシリアルポートdllを開発しています(MASM32
)。複数のイベントをチェックする独自のスレッドがあり、指定されたバッファーしきい値で、コールバック関数を呼び出して管理対象のメインアプリケーションに通知します。これは、引数/戻り値のない単なる呼び出しです。
起動時に、メインアプリケーションはdll内の関数を呼び出すことにより、コールバック関数のアドレスを格納します。
pCallBackFunction dd 0
SetCallBackPointer proc pcb:DWORD
mov eax, pcb
mov pCallBackFunction, eax
call DWORD ptr pCallBackFunction ; verify it immediately
ret
SetCallBackPointer endp
上の関数は、検証のためにマネージドアプリケーションのコールバックルーチンをすぐに呼び出します。正常に動作しています。ただし、dll内の他の関数への呼び出し命令を配置すると、アプリケーションがクラッシュします。呼び出しが単純な関数であるか、dllのthreadprocであるかは関係ありません。例えば:
OpenPort proc pn:byte,br:dword, inputbuffersize: dword, outputbuffersize:dword, thresholdsize: dword
LOCAL dcb: DCB
LOCAL SerialTimeOuts: COMMTIMEOUTS
call DWORD ptr pCallBackFunction
xor eax, eax
mov al, pn
mov [com_port+3],al
etc. etc.
常にDWORDptrpCallBackFunctionを呼び出すとクラッシュします。最初にSetCallBackPointerを呼び出して有効なアドレスをpCallBackFunctionに格納するので、有効なアドレスが必要です。
私の管理対象アプリはC#で記述されており、関連する部分は次のとおりです。
public partial class Form1 : Form
{
public delegate void CallBackDelegate();
public static CallBackDelegate mydelegate;
[DllImport("serialport.dll")]
private static extern void SetCallBackPointer(CallBackDelegate Delegate);
[DllImport("serialport.dll")]
public static extern int OpenPort(byte com, uint br, uint inbufsize, uint outbufsize, uint threshsize);
public Form1()
{
InitializeComponent();
mydelegate =new CallBackDelegate(CallbackFunction);
SetCallBackPointer(mydelegate);
unsafe
{
int sysstat;
int hResult;
hResult = OpenPort(Convert.ToByte('5'), 9600, 306, 4, 4);
}
}
public static void CallbackFunction()
{
MessageBox.Show( "CallBack Function Called by Windows DLL");
}
VSデバッガーは、dllが保護されたメモリアドレスとの間で読み取り/書き込みを試みたことを報告しました。ただし、SetCallBackPointerを呼び出す場合、そのような問題はありません。私はここで何が間違っているのですか?
どんなヒントも素晴らしいでしょう!