我正在開發win32程序集中的串口dll(MASM32
)。它有自己的線程檢查多個事件,並在指定的緩衝區閾值處通過調用回調函數通知託管的主應用程序。這只是一個沒有參數/返回值的調用。從非託管win32程序集DLL調用託管代碼 - 崩潰
在啓動時的主應用程序商店的回調函數的地址由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.
會在調用DWORD ptr pCallBackFunction時崩潰。由於我先調用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時,不存在這樣的問題。我在這裏做錯了什麼?
任何提示將是偉大的!
如果您確信一切正確的是(pCallBackFunction不會被覆蓋)你檢查了調用約定(OpenPort有很多參數和返回值)嗎? –
順便說一下...... + 1,因爲即使我無法確定原因,你仍然在組裝中寫作! –
當我打電話給dword ...指令時,OpenPort工作正常。我將添加額外的函數來檢查是否覆蓋pCallBackFunction。 這只是練習,沒有真正的原因背後編寫彙編。謝謝。 – JustGreg