【发布时间】:2015-12-08 03:19:29
【问题描述】:
当我在 Windows 64 位 (Windows 7) 上的 32 位应用程序中使用 longjmp 时出现问题。它没有返回到最后一次 setjmp() 调用的某个点,而是在最后一次 DispatchMessage() 调用之后着陆。这是代码示例,如果由 64 位编译器编译,则可以正常工作,而在 32 位版本中编译失败。
有什么解决方法的想法吗?微软似乎在这里对一个切题的问题保持沉默:https://social.msdn.microsoft.com/Forums/vstudio/en-US/b63a573f-007e-43a3-877c-b06280aa8bcc/0x80000026-application-error-when-exiting-after-using-longjmp-on-windows8-x64?forum=windowscompatibility
// Compile as: cl a.c user32.lib kernel32.lib
#include <windows.h>
#include <setjmp.h>
#include <stdio.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
jmp_buf jump_buffer;
int flag = 0;
int main()
{
WNDCLASS wc = {0, };
ATOM atom = 0;
HWND wnd;
MSG msg;
int ret;
wc.lpfnWndProc = &WndProc;
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = "ExitWindows() handler";
atom = RegisterClass(&wc);
wnd = CreateWindow(wc.lpszClassName, wc.lpszClassName,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, wc.hInstance, NULL);
ret = setjmp(jump_buffer);
switch ( ret ) {
case 0:
ShowWindow(wnd,SW_SHOW);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
if ( flag ) {
printf("not ok\n");
break;
}
}
break;
case 1:
printf("ok\n");
break;
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_PAINT:
flag = 1;
longjmp(jump_buffer, 1);
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
【问题讨论】:
-
您正在跨越不受您控制的代码。使用
setjmp/longjmp时,您必须确保每个人都在开玩笑。在您拨打DispatchMessage和WndProc之间的所有事情都没有为这个噱头做好准备。如果它似乎在 64 位版本中工作,那只是巧合。 -
如果 goto 被认为是有害的,这是什么?你为什么要重新输入
main()?如果目标是在您获得第一次绘画时退出您的消息循环...there are better ways -
ret = setjmp(jump_buffer);您可以在 conditional 中测试 setjmp() 的“返回”值,但您不应该在作业中使用它。 -
它在 C 标准中,从 c89,IIRC 开始。也许 c.l.c 存档/常见问题解答? GIYF BTW:MSDN 不是信息来源。 (好吧,也许是关于实现或使用的东西)另外:你的
flag应该真的是不稳定的,
标签: c winapi 32bit-64bit setjmp