我正在尝试在Windows 7中使用带有C ++功能的WscRegisterForChanges。
位于此处的文档:
http://msdn.microsoft.com/en-us/library/bb432507(v=VS.85).aspx
我的问题是,即使回调正确执行,代码也会在回调执行结束时崩溃。
这是有问题的代码。这很简单,所以我不确定它为什么会崩溃:
#include #include #include void SecurityCenterChangeOccurred(void *param) { printf("Change occurred!\n"); } int main() { HRESULT result = S_OK; HANDLE callbackRegistration = NULL; result = WscRegisterForChanges( NULL, &callbackRegistration, (LPTHREAD_START_ROUTINE)SecurityCenterChangeOccurred, NULL); while(1) { Sleep(100); } return 0; }
崩溃发生时我的调用堆栈如下所示:
> 00faf6e8() ntdll.dll!_TppWorkerThread@4() + 0x1293 bytes kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
如果我添加ExitThread(0);在SecurityCenterChangeOccurred结束时,我得到一个错误和以下跟踪(所以我不认为我应该使用ExitThread):
Unhandled exception at 0x7799852b (ntdll.dll) in WscRegisterForChangesCrash.exe: 0xC000071C: An invalid thread, handle %p, is specified for this operation. Possibly, a threadpool worker thread was specified. ntdll.dll!_TpCheckTerminateWorker@4() + 0x3ca2f bytes ntdll.dll!_RtlExitUserThread@4() + 0x30 bytes > WscRegisterForChangesCrash.exe!SecurityCenterChangeOccurred(void * param=0x00000000) Line 8 + 0xa bytes C++ wscapi.dll!WorkItemWrapper() + 0x19 bytes ntdll.dll!_RtlpTpWorkCallback@8() + 0xdf bytes ntdll.dll!_TppWorkerThread@4() + 0x1293 bytes kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
有没有人有任何想法可能会发生这种情况?
要触发崩溃,请运行程序并打开或关闭防火墙。
答案 0 :(得分:2)
这是由于调用约定。 WinApi32函数的定义|回调必须以宏WINAPI或CALLBACK开头,它基本上告诉编译器有关调用约定 - 要推送到堆栈的参数的顺序,应该写入返回值,返回调用者后的堆栈恢复。
总结一下,CC定义了来电者和被叫者之间的关系
答案 1 :(得分:0)
看起来将WINAPI添加到回调修复此问题。
新电话如下:
void WINAPI SecurityCenterChangeOccurred(void *param) { printf("Change occurred!\n"); }
有人可以告诉我为什么这是必要的吗?