注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

mie

 
 
 

日志

 
 

【解决】VC 2008:线程中调用CreateWindowEx失败(内存排列问题)  

2010-07-12 17:23:40|  分类: 疑难杂症 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

代码如下:

调用:Create(WorkerWindowProc, NULL);

Create的实现:
int Create(WNDPROC window_proc, HINSTANCE hins)
{
 WNDCLASSEX wcex= {0};

 wcex.cbSize = sizeof(WNDCLASSEX);
 wcex.style = CS_HREDRAW | CS_VREDRAW;
 wcex.lpfnWndProc = window_proc;
 wcex.cbClsExtra = 0;
 wcex.cbWndExtra = 0;
 wcex.hInstance = hins;
 wcex.hIcon = NULL;
 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
 wcex.lpszMenuName = NULL;
 wcex.lpszClassName = COMMON_THREAD_WINDOW_CLASS_NAME;
 wcex.hIconSm = NULL;

 ATOM atom=RegisterClassEx(&wcex);

 if(atom==0  &&
  ERROR_CLASS_ALREADY_EXISTS!=GetLastError())
 {
  return   FALSE;
 }

 m_hWnd = CreateWindowEx(
  0,
  COMMON_THREAD_WINDOW_CLASS_NAME,
  COMMON_THREAD_WINDOW_WINDOW_NAME,
  0, 0, 0, 0, 0, NULL, NULL, hins, NULL);

 return m_hWnd==NULL?-1:0;
}

窗口过程函数:
LRESULT CALLBACK WorkerWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 LRESULT ret=S_OK;

 ret=DefWindowProc(hWnd, message, wParam, lParam);

 return ret;
}

        这段代码在VC2005中正常,在VC2008的MFC程序主界面线程中调用也正常。但是,在自己创建的线程中调用,并使用VC2008编译,失败,提示“未处理的异常: 0xC0000005,写入0xxxxxxxxx时发生访问冲突”。

 

反汇编:
 m_hWnd = CreateWindowEx(
  0,
  COMMON_THREAD_WINDOW_CLASS_NAME,
  COMMON_THREAD_WINDOW_WINDOW_NAME,
  0, 0, 0, 0, 0, NULL, NULL, hins, NULL);
0053CD67 8B F4            mov         esi,esp
0053CD69 6A 00            push        0   
0053CD6B 8B 45 0C         mov         eax,dword ptr [hins]
0053CD6E 50               push        eax 
0053CD6F 6A 00            push        0   
0053CD71 6A 00            push        0   
0053CD73 6A 00            push        0   
0053CD75 6A 00            push        0   
0053CD77 6A 00            push        0   
0053CD79 6A 00            push        0   
0053CD7B 6A 00            push        0   
0053CD7D 68 B0 C6 74 00   push        offset string L"Window_T_Text_%d" (74C6B0h)
0053CD82 68 84 A2 74 00   push        offset string L"Window_T_%d" (74A284h)
0053CD87 6A 00            push        0   
0053CD89 FF 15 54 B3 7B 00 call        dword ptr [__imp__CreateWindowExW@48 (7BB354h)]
0053CD8F 3B F4            cmp         esi,esp
0053CD91 E8 82 AF FD FF   call        @ILT+36115(__RTC_CheckEsp) (517D18h)
0053CD96 8B 4D F8         mov         ecx,dword ptr [this]
0053CD99 89 41 04         mov         dword ptr [ecx+4],eax

出错代码在0053CD99 处,dword ptr [ecx+4]为NULL,赋值给空指针,导致上面的异常提示。而导致这一问题的根本原因在于0053CD96处。

mov         ecx,dword ptr [this]
将this指针赋给ecx寄存器,然后

0053CD99 89 41 04         mov         dword ptr [ecx+4],eax

ecx偏移4个字节,得到m_hWnd的地址,然后从eax寄存器取出返回值,并赋值给m_hWnd变量。但是,在赋值给m_hWnd变量的时候,出现错误!

 

于是,
 HWND hwnd = CreateWindowEx(
  0,
  COMMON_THREAD_WINDOW_CLASS_NAME,
  COMMON_THREAD_WINDOW_WINDOW_NAME,
  0, 0, 0, 0, 0, NULL, NULL, hins, NULL);

 m_hWnd=hwnd;

 return m_hWnd==NULL?-1:0;

 

这时候,异常出现在m_hWnd=hwnd;,看来,问题不在CreateWindowEx这儿,而是m_hWnd!

 

为什么成员变量会出现这种情况?栈溢出?

于是,将栈内存分配改成堆内存分配(局部成员变量改成new动态分配内存变量),问题依旧存在。

 

内存对齐导致的问题?

调整类成员变量的先后位置,OK!

 

具体原因不详,虽然跟踪了内存的分配,但是并未发现有什么异常的地方。

 

解决!我把线程函数的参数弄错了!没想到程序居然没报错,而且还把线程给创建出来了。但是,很多参数都出错了。之后,发现这些参数不对,步步跟踪,才找到原因。

 

By:zhanyonhu

  评论这张
 
阅读(1407)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016