整个工程分为3部分,一个对话框EXE,两个MFC的DLL,相关代码如下:
//对话框EXE:(就一个按钮)
void CTestDlg::OnButton1() 
{
// TODO: Add your control notification handler code here
HINSTANCE hdll = LoadLibrary("Dll1.dll");
pFunc1 myfunc;
CString str;
int code;
myfunc = (pFunc1)GetProcAddress(hdll, "Func1");

code = myfunc(NULL, NULL);
str.Format("%d", code);
MessageBox(str);

FreeLibrary(hdll);
}//Dll2.dll:(一个接口)
DLLEXPORT int WINAPI Func1(HANDLE handle, char *pCode)
{
int flag;
CMyDlg dlg;
dlg.DoModal();
flag = dlg.ExitCode;
return flag;
}
//作用是弹出一个对话框(同样只有一个Button),对话框代码如下:
void CMyDlg::OnButton1() 
{
// TODO: Add your control notification handler code here
pFunc2 func;
HINSTANCE hdll = LoadLibrary("Dll2.dll");
if(hdll == NULL)
{
MessageBox("load dll error!");
return;
}
if((func = (pFunc2)GetProcAddress(hdll, "Func2")) == NULL) 
{
FreeLibrary(hdll);
MessageBox("load function error!");
return;
} if(func(NULL, NULL, 0) != 0)
{
MessageBox("Not 0!");
return;
} ExitCode = 0; //ExitCode是对话框类成员变量
FreeLibrary(hdll);
this->OnCancel();
}//Dll2.dll:(一个接口)
DLLEXPORT int WINAPI Func2(HANDLE handle, char *pChallenge, int ChallengeLen)
{
CMyDlg dlg;
dlg.DoModal();
//Sleep(100); 如果延迟100毫秒就一切正常,否则90%出错
return dlg.errorcode;
}
//作用是弹出一个对话框,对话框相关代码如下:
BOOL CMyDlg::OnInitDialog() 
{
CDialog::OnInitDialog();

// TODO: Add extra initialization here
pMyThread = AfxBeginThread((AFX_THREADPROC)StartThread, this);
pMyThread->m_bAutoDelete = TRUE;
return TRUE;  // return TRUE unless you set the focus to a control
              // EXCEPTION: OCX Property Pages should return FALSE
}
void CMyDlg::ShowTips(CString tips)
{
m_tips.SetWindowText((LPCTSTR)tips); //显示文本框
m_tips.RedrawWindow();
}
void CMyDlg::ShowGood()
{
//使picture控件显示一幅图片,持续1秒然后关闭对话框
CBitmap good;
DWORD flag;
good.LoadBitmap(IDB_GOOD);
m_goodwrong.SetBitmap((HBITMAP)good); //m_goodwrong是一个picture控件对象
m_goodwrong.RedrawWindow();
Sleep(1000);
errorcode = 0; //errorcode是对话框类成员变量
this->OnCancel();
}
//线程函数:
void StartThread(CMyDlg *dlg)
{
Sleep(1000);
dlg->ShowTips("成功!");
dlg->ShowGood();
ExitThread(0);
return;
}功能简述:
运行程序,按下对话框EXE的button1,弹出Dll1.dll的对话框,然后再按下Dll1.dll的对话框的button1,会弹出Dll2.dll的对话框并显示一些东西,然后自动关闭,退回到对话框EXE界面。
可是我运行结果却是所有对话框一起关闭了,就好像进程关闭了一样。几乎每次都是这样,可是只要在Dll2.dll的接口那里延迟100毫秒返回不会出错,不知道是不是线程同步问题,请哪位达人指教下。

解决方案 »

  1.   

    问题解决了,是因为我试图在线程中关闭窗口导致的一些潜在问题造成的:在没有确认线程已经结束的情况下Cancel掉了Dialog。
    解决方法:在CMyDlg::ShowGood()中取消this->OnCancel();这句,在线程中对CMyDlg发送自定义消息(用Post),在CMyDlg中接收该消息并Cancel掉Dialog就行了。
      

  2.   

    忘写了,在Cancel掉Dialog前WaitForSingleObject等待线程结束
      

  3.   

    恭喜,但在dll的导出函数中如果要用到资源还要加上 AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
    否则当主程序的资源和dll资源中有相同的id时会报错。