国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
請教個小問題, 跨線程傳窗口對象指針,程序崩潰
UINT Ctest8Dlg:: ThreadProc(LPVOID p){/*Ctest8Dlg* pthis=(Ctest8Dlg*)p;pthis->m_str=_T("hello");pthis->UpdateData(FALSE);*/Ctest8Dlg obj;HWND hWnd=(HWND)p;obj.Attach(hWnd);obj.m_str=_T("xx");obj.UpdateData(FALSE);obj.Detach();return 0;}代碼出現(xiàn)的意義在于驗(yàn)證 網(wǎng)上流傳的跨線程傳遞窗口對象指針的法子是否正確,所以回答:采用發(fā)送消息給ui線程的人 勿擾。謝謝。



問題2: 

故意多次去釋放dll里的內(nèi)存,程序死活不崩潰。 

dll里: 

char* _stdcall Test() 

return  new char[50]; 

}; 

exe里: 

for(int i=0; i<50;i++) 

char* p=Test(); 
delete []p; 


這么多次循環(huán), 程序也不崩潰 




回復(fù)討論(解決方案)

用指針: 
Ctest8Dlg *pDlg = FromHandle(hWnd);
用指針: 
Ctest8Dlg *pDlg = FromHandle(hWnd); 

pthis->m_str=CString(_T("hello")); 
按照你的修改,這一句崩潰了 

原因不詳細(xì)。 







另外: 你提供的法子,似乎是什么臨時的,網(wǎng)上有,但是我沒有看懂,臨時是否說明: 

有隱患呢? 

2個問題,謝謝解答。 

問題1: 
因?yàn)锳fxBeginThread內(nèi)部已經(jīng)Attach了一次主界面 
		CWnd threadWnd;....		// thread inherits app's main window if not already set		CWinApp* pApp = AfxGetApp();...		threadWnd.Attach(pApp->m_pMainWnd->m_hWnd);		pThread->m_pMainWnd = &threadWnd;

所以再次Attach是會斷言在 
ASSERT(FromHandlePermanent(hWndNew) == NULL);		// must not already be in permanent map

同一線程不能多次Attach同一窗口? 
忽略彈出窗口,可繼續(xù)執(zhí)行。 

如果用CWnd::FromHandle,獲得的將是上面的(&threadWnd)指針 
由于是CWnd實(shí)體對象,強(qiáng)轉(zhuǎn)為Ctest8Dlg對象后,因?yàn)閙_str不是CWnd成員,pthis->m_str可能會破壞內(nèi)存 或出現(xiàn)不可預(yù)料的結(jié)果 

解決方法之一是將AfxBeginThread換成_beginthreadex(NULL, 0, ThreadProc, m_hWnd, 0, NULL); 
另外記得在ThreadProc加上WINAPI(__stdcall) 
static UINT WINAPI ThreadProc(LPVOID p);

使用Attach的方法 
如果用CWnd::FromHandle,還是會出錯,因?yàn)榇藭r獲得是臨時的CWnd*對象指針,強(qiáng)轉(zhuǎn)為Ctest8Dlg*后,同樣會出錯。 


問題2 
這個起因是分配和釋放的CRT Heap不相同造成 
CRT源碼里有一個全局句柄HANDLE _crtheap 

如果exe和dll都使用動態(tài)DLL編譯,那么這個_crtheap只會存在一個,在msvcrXX.dll里 
另外3中情況,靜態(tài)編譯會將_crtheap編譯進(jìn)去,就會出錯 
exe動態(tài) 和 dll靜態(tài)編譯:msvcrXX.dll和dll各1份_crtheap 
exe靜態(tài) 和 dll動態(tài)編譯:msvcrXX.dll和exe各1份_crtheap 
exe靜態(tài) 和 dll靜態(tài)編譯:exe和dll各1份_crtheap 
1. 
Ctest8Dlg *pDlg = (Ctest8Dlg *)p; 

obj.m_str=_T("xx"); //這種操作本身不安全 

比較好的方法是SendMessage以自定義消息的形式通知pDlg來修改m_str的值。絕對不會崩潰。 

SendMessage(pDlg->GetSafeHwnd(),自定義消息編號,參數(shù)1,參數(shù)2); 


2.為什么要崩潰?我倒不理解了。 
樓主指針概念有問題吧。 
問題1: 
因?yàn)锳fxBeginThread內(nèi)部已經(jīng)Attach了一次主界面 
C/C++ code12345678        CWnd threadWnd;....        // thread inherits app's main window if not already set        CWinApp* pApp = AfxGetApp();...…… 

你好,老師 

問題2 待會驗(yàn)證回復(fù)你 

問題1 

我似乎沒有在帖子里提到用AfxBeginThread吧,最初我是用它創(chuàng)建線程,靈機(jī)一動,換成CreateThread 

原因是這個函數(shù)是 mfc提供的,怕其不崩潰,所以換成win32的,創(chuàng)建線程后,依然崩潰。 

所以你對其的回復(fù),可能不是很精準(zhǔn)。 

代碼為: CreateThread(NULL,0,ThreadProc,this,0,NULL); 

線程代碼為: 

DWORD WINAPI Ctest8Dlg:: ThreadProc(LPVOID p) 

Ctest8Dlg* pthis=(Ctest8Dlg*)FromHandle((HWND)p); 
pthis->m_str=CString(_T("hello")); 
pthis->UpdateData(FALSE); 

/*Ctest8Dlg obj; 
HWND hWnd=(HWND)p; 

obj.Attach(hWnd); 

obj.m_str=_T("xx"); 
obj.UpdateData(FALSE); 
obj.Detach();*/ 
return 0; 


線程函數(shù),我知道發(fā)送消息其實(shí)是可以解決的,但是不選擇發(fā)送消息的路線,是因?yàn)轵?yàn)證 

采用attach或者 FromHandle的法子如何解決。 

這是第一個帖子的目的。 

謝謝大家。 

問題1: 
因?yàn)锳fxBeginThread內(nèi)部已經(jīng)Attach了一次主界面 
C/C++ code12345678        CWnd threadWnd;....        // thread inherits app's main window if not already set        CWinApp* pApp = AfxGetApp();...…… 

問題2:4中情形我都驗(yàn)證了,卻是如你所說的。 

順便問一句,,困惑很久的一個小技巧 

從vs2008開始,所有的工程里有個工程屬性叫:  
mfc的使用,有3個選項(xiàng): 

使用標(biāo)準(zhǔn)windows庫 
mfc共享 
mfc靜態(tài) 

非mfc工程,默認(rèn)是mfc共享,     mfc靜態(tài)自然是你說的 靜態(tài)編譯了 

那么使用標(biāo)準(zhǔn)windows庫是什么東西? 

比如:我想寫一個超級簡單的控制臺程序,然后發(fā)布出去,選擇哪一個? 

此時,是不是有些無奈? 多了一個window標(biāo)準(zhǔn)庫。               

如果是我,我選擇靜態(tài)mfc。 

實(shí)在不知道widnows 標(biāo)準(zhǔn)庫是靜態(tài)的,還是動態(tài)等。 

老師,你有空,可以幫我看看,謝謝 

1. 
Ctest8Dlg *pDlg = (Ctest8Dlg *)p; 

obj.m_str=_T("xx"); //這種操作本身不安全 

比較好的方法是SendMessage以自定義消息的形式通知pDlg來修改m_str的值。絕對不會崩潰。 

SendMessage(pDlg->GetSafeHwnd(),自定義消息編號,參數(shù)1,參數(shù)2); 


2…… 

看我的回復(fù),我已經(jīng)驗(yàn)證,卻是崩潰了
MFC規(guī)定了一個線程僅僅能訪問它所創(chuàng)建的MFC對象。 
為了阻止多個線程并發(fā)的訪問同一個MFC對象,MFC對象和WIndows對象之間有一個一一對應(yīng)的關(guān)系。這種關(guān)系以映射的形式保存在創(chuàng)建線程的當(dāng)前模塊的模塊-線程狀態(tài)信息中。當(dāng)一個線程使用某個MFC對象指針P時,ASSERT_VALID(p)將驗(yàn)證當(dāng)前線程的當(dāng)前模塊是否有Windows句柄和p對應(yīng),即是否創(chuàng)建了p所指的Windows對象,驗(yàn)證失敗導(dǎo)致ASSERT斷言中斷程序的執(zhí)行,如果一個線程要使用其它線程的Windows對象,則必須傳遞Windows對象的句柄,不能傳遞MFC對象的指針。 
http://support.microsoft.com/kb/147578/zh-cn?wa=wsignin1.0
MFC規(guī)定了一個線程僅僅能訪問它所創(chuàng)建的MFC對象。 
為了阻止多個線程并發(fā)的訪問同一個MFC對象,MFC對象和WIndows對象之間有一個一一對應(yīng)的關(guān)系。這種關(guān)系以映射的形式保存在創(chuàng)建線程的當(dāng)前模塊的模塊-線程狀態(tài)信息中。當(dāng)一個線程使用某個MFC對象指針P時,ASSERT_VALID(p)將驗(yàn)證當(dāng)前線程的當(dāng)前模塊是否有Windows句柄和p對應(yīng),即是否創(chuàng)建了p所指的Wi…… 

老師你好,對于這個知識點(diǎn),我早有所聞, 

只是不知道為什么mfc要有這么個規(guī)定 

mfc一共引入了4個狀態(tài):模塊狀態(tài),線程狀態(tài), 模塊-線程狀態(tài), 

進(jìn)程狀態(tài)。 

前3個狀態(tài)似乎是為 mfc的tls服務(wù)的, 

理解起來也比較費(fèi)勁。 



DWORD WINAPI Ctest8Dlg:: ThreadProc(LPVOID p) 
 { 
 Ctest8Dlg* pthis=(Ctest8Dlg*)FromHandle((HWND)p); 
 pthis->m_str=CString(_T("hello")); 
 pthis->UpdateData(FALSE); 
  
/*Ctest8Dlg obj; 
 HWND hWnd=(HWND)p; 
  
obj.Attach(hWnd); 
  
obj.m_str=_T("xx"); 
 obj.UpdateData(FALSE); 
 obj.Detach();*/ 
 return 0; 
 } 
  
我已經(jīng)按照這個法子了,依然會有崩潰。 

崩潰在m_str賦值這里,原因不詳! 

原因是FromHandle這個函數(shù)返回的是CWnd*指針,但是你將它強(qiáng)制轉(zhuǎn)化成了Ctest8Dlg*指針,這樣本身就是很危險(xiǎn)的,而你后面又訪問了Ctest8Dlg類自己定義的成員變量(而這個成員變量在CWnd類中并沒有定義它),所以這里就錯了。
原因是FromHandle這個函數(shù)返回的是CWnd*指針,但是你將它強(qiáng)制轉(zhuǎn)化成了Ctest8Dlg*指針,這樣本身就是很危險(xiǎn)的,而你后面又訪問了Ctest8Dlg類自己定義的成員變量(而這個成員變量在CWnd類中并沒有定義它),所以這里就錯了。 


有些道理, 

CWnd的派生類過多,而且其本身也有基類,那么最終拍攝各類Ctest8dlg* 所指向的內(nèi)存就不是爺爺基類 
Cwnd的地址了,所以這里就錯誤了。 

如此說來, 

這個法子是個雞肋了, 

對任何CWnd的派生類來說,都比較危險(xiǎn),除非用該指針去訪問 

CWnd的成員函數(shù)才沒事情, 否則只要訪問派生類CDialog 或者Ctest8dlg里的 

自己增加的函數(shù)或者成員,都會出錯。 

引用 10 樓 VisualEleven 的回復(fù):原因是FromHandle這個函數(shù)返回的是CWnd*指針,但是你將它強(qiáng)制轉(zhuǎn)化成了Ctest8Dlg*指針,這樣本身就是很危險(xiǎn)的,而你后面又訪問了Ctest8Dlg類自己定義的成員變量(而這個成員變量在CWnd類中并沒有定義它),所以這里就錯了。 


有些道理, 

CWnd的派生類過多,而且其本身也有基類,那么最終…… 

CWnd* pthis=FromHandle((HWND)p); 
//pthis->m_str=CString(_T("hello")); 

if(pthis) 

pthis->SetWindowText(_T("xx")); 

setwindowtext 崩潰。 

說明這個法子,太危險(xiǎn)了, 很多東西搞不定。 

指針我調(diào)試過了,是有值的。 


雞肋法子啊,都不知道CWnd的哪一個成員函數(shù)可以使用了。 
引用 10 樓 VisualEleven 的回復(fù):原因是FromHandle這個函數(shù)返回的是CWnd*指針,但是你將它強(qiáng)制轉(zhuǎn)化成了Ctest8Dlg*指針,這樣本身就是很危險(xiǎn)的,而你后面又訪問了Ctest8Dlg類自己定義的成員變量(而這個成員變量在CWnd類中并沒有定義它),所以這里就錯了。 


有些道理, 

CWnd的派生類過多,而且其本身也有基類,那么最終…… 
訪問函數(shù)沒有關(guān)系,只要該函數(shù)中沒有訪問該類中自己定義的成員變量即可 

this = 0x002cfdc4 {Ctest8Dlg hWnd=0x00680342} 

pthis = 0x001a9eac {CWnd hWnd=0x00680342} 

這是我做的實(shí)驗(yàn), 在線程里獲得CWnd指針是最后那個, CXXdlg指針是上的那個。 

可見,F(xiàn)romHandle獲得的指針是祖父類的。并非孫類的。 

那么自然就不能使用祖父類的指針去調(diào)用非祖父類的函數(shù)了,對吧。 

除非動態(tài)綁定技術(shù)。 

這個從c++語法的角度分析,我覺得沒有問題吧。 

順便糾正12樓,12樓是錯誤的,  

原因在于,我傳參數(shù)的時候,不小心沒有把句柄,從線程里傳進(jìn)去。  

是我的失誤
引用 3 樓 stjay 的回復(fù):問題1: 
因?yàn)锳fxBeginThread內(nèi)部已經(jīng)Attach了一次主界面 
C/C++ code12345678        CWnd threadWnd;....        // thread inherits app's main window if not already set        CWinApp* pApp …… 




同時跟正第5樓的實(shí)驗(yàn) 

和 
15樓一樣, 線程傳參數(shù)失誤了, 代碼是沒有問題的。 

感謝大家的熱心解答。 



引用 3 樓 stjay 的回復(fù):問題1: 
因?yàn)锳fxBeginThread內(nèi)部已經(jīng)Attach了一次主界面 
C/C++ code12345678        CWnd threadWnd;....        // thread inherits app's main window if not already set        CWinApp* pApp …… 


剩下第6樓的問題 

windows標(biāo)準(zhǔn)庫是動態(tài)的,還是靜態(tài)編譯的? 
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
m_pMainWnd是MFC中的一個全局指針變量
映射窗口句柄對象
在MFC中從一個線程工作函數(shù)中向窗口發(fā)送消息(this指針的妙用) ---不好用呢
VC++中有關(guān)句柄和指針及其轉(zhuǎn)換
VC|MFC學(xué)習(xí)筆記六: 幾個小知識(I)--全域函數(shù),數(shù)據(jù)類型,CWnd和HWnd等
子類化和超類化區(qū)別(轉(zhuǎn)自--眼見為實(shí)(2):介紹Windows的窗口、消息、子類化和超類化...
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服