首先我是创建了一个win32的dll工程:多线程调试 DLL (/MDd)以及使用标准 Windows 库这样的属性,我的测试工程是一个win32控制台引用程序,相应的属性DLL (/MDd)使用标准 Windows 库。主要是通过win32控制台应用程序来测试dll存在的问题,各种纠结,总结一下整个过程遇到的问题和相应的解决方法以备以后的参考学习,感谢各种大神!
在dll工程里面:
这里由于使用了mfc的窗口类所以要添加相应的mfc的头文件如下:
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
注意一定要在所有的头文件之前加入这几行,而起顺序最好不要改变,否则会有大量的错误提示。
(1)定义窗口类class MyClassDlg : public CDialog
{
public':
MyClassDlg(int ch=0,CWnd* pParent = NULL); // standard constructor
~MyClassDlg();
enum { IDD = IDD_DIALOG1 };
protected:
HICON m_hIcon;
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
virtual LRESULT WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP();
void InitIntelligentAnalysis(int ch=0, int task=0);
private:
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedCancel();
}
我要创建这个窗口通过重载WindowProc处理别的地方发到这个窗口的消息,这里我启动了一个模态窗口:调用窗口类的DoModal()方法去启动窗口,由于所启动的窗口是模态的会阻塞之后的所有操作,所以通过创建一个新的线程_beginthread()来启动这个窗口类。之后就是遇到的各种问题了:
(1)首先是第一个错误:(这里的处理断言类的错误很值得参考)
vs70builds\3077\vc\MFCATL\ship\atlfmc\include\afxwin1.ini line:26
这是一个断言错误
////////////////////////////////////////////////////////////////
Assert 断言处理
1、在VC安装目录下搜出错文件(也有可能是在你的工作目录下);
2、找到Assert提示的错误行,看看是在哪一个函数中发生的断言,判断这是由于哪一方面出现的断言(如窗口的创建,等等);
3、在你的程序中设置断点,断点跟踪一下你的代码,直到找到和错误最接近的代码口;
4、修改你的代码。
////////////////////////////////////////////////////////////////
通过一步步的跟进DoModal()方法,发现是这样这里出了问题ASSERT(afxCurrentResourceHandle != NULL);
上网搜了一下针对这个问题的处理方法:
搜集网络资料发现这个错误的原因是这里用了MFC的类但是没有对mfc类调用初始化:
网络资料:http://blog.csdn.net/wuyong2k/article/details/7836105
解决办法:
在模块初始化后,要使用的MFC类前,添加如下代码:
//MFC初始化
if(!AfxWinInit(::GetModuleHandle(NULL),NULL,::GetCommandLine(),0))
{
return 1;
}
(2)第二个错误:
加入这句话之后,现在不会报ASSERT(afxCurrentResourceHandle != NULL);这个错误了,但是还有一个问题是;创建的窗口没有有效的句柄。为了解决这个问题,还是求助于强大的网络和各位大神:搜索之后的解决办法是加入在dll的导出接口加入下面的这句:
AFX_MANAGE_STATE(AfxGetStaticModuleState());
这篇文章讲解的不错网络资料:http://www.cnblogs.com/ntrgx/archive/2010/11/14/1877199.html