0

我正在尝试在 Windows 7 中将 WscRegisterForChanges 与 C++ 函数一起使用。

文档位于此处:

http://msdn.microsoft.com/en-us/library/bb432507(v=VS.85).aspx

我的问题是,即使回调正确执行,代码在回调执行结束时也会崩溃。

这是有问题的代码。这很简单,所以我不确定它为什么会崩溃:

#包括
#包括
#包括

void SecurityCenterChangeOccurred(void *param) {
 printf("发生变化!\n");
}

int main() {
 HRESULT 结果 = S_OK;
 处理回调注册 = NULL;

 结果 = WscRegisterForChanges(
  无效的,
  &回调注册,
  (LPTHREAD_START_ROUTINE)SecurityCenterChange 发生,
  无效的);

 而(1){
  睡眠(100);
 }

 返回0;
}

发生崩溃时,我的调用堆栈如下所示:

> 00faf6e8()
  ntdll.dll!_TppWorkerThread@4() + 0x1293 字节
  kernel32.dll!@BaseThreadInitThunk@12() + 0x12 字节
  ntdll.dll!___RtlUserThreadStart@8() + 0x27 字节
  ntdll.dll!__RtlUserThreadStart@8() + 0x1b 字节

如果我添加 ExitThread(0); 到 SecurityCenterChangeOccurred 结束时,我得到一个错误和以下跟踪(所以我认为我不应该使用 ExitThread):

WscRegisterForChangesCrash.exe 中 0x7799852b (ntdll.dll) 处的未处理异常:0xC000071C:为此操作指定了无效线程句柄 %p。可能指定了线程池工作线程。

  ntdll.dll!_TpCheckTerminateWorker@4() + 0x3ca2f 字节
  ntdll.dll!_RtlExitUserThread@4() + 0x30 字节
> WscRegisterForChangesCrash.exe!SecurityCenterChangeOccurred(void * param=0x00000000) 第 8 行 + 0xa 字节 C++
  wscapi.dll!WorkItemWrapper() + 0x19 字节
  ntdll.dll!_RtlpTpWorkCallback@8() + 0xdf 字节
  ntdll.dll!_TppWorkerThread@4() + 0x1293 字节
  kernel32.dll!@BaseThreadInitThunk@12() + 0x12 字节
  ntdll.dll!___RtlUserThreadStart@8() + 0x27 字节
  ntdll.dll!__RtlUserThreadStart@8() + 0x1b 字节

有谁知道为什么会发生这种情况?

要触发崩溃,请运行​​程序并打开或关闭防火墙。

4

2 回答 2

2

这是由于调用约定。WinApi32函数的定义|回调必须在宏WINAPI或CALLBACK之前,它基本上告诉编译器调用约定-参数被压入堆栈的顺序,应该在哪里写入返回值,返回给调用者后的堆栈恢复。

综上所述,CC定义了caller和callee之间的关系

于 2011-12-14T14:02:59.430 回答
0

似乎将 WINAPI 添加到回调中可以解决此问题。

新调用如下所示:

void WINAPI SecurityCenterChangeOccurred(void *param) {
    printf("发生变化!\n");
}

有人能告诉我为什么这是必要的吗?

于 2010-05-07T06:23:21.023 回答