1、VS2003新建DLL项目dllTest
2、项目dllTest中添加类CDllDailog
3、切换到Resource view界面,添加新Button(ID:IDC_BUTTON_Hello Caption:Hello),并点击进入DllDialog.cpp脚本,添加代码如下(红色):
1 #include "stdafx.h" 2 #include "dllTest.h" 3 #include "DllDialog.h" 4 #include ".\dlldialog.h" 5 6 7 // CDllDialog dialog 8 9 IMPLEMENT_DYNAMIC(CDllDialog, CDialog) 10 CDllDialog::CDllDialog(CWnd* pParent /*=NULL*/) 11 : CDialog(CDllDialog::IDD, pParent) 12 { 13 } 14 15 CDllDialog::~CDllDialog() 16 { 17 } 18 19 void CDllDialog::DoDataExchange(CDataExchange* pDX) 20 { 21 CDialog::DoDataExchange(pDX); 22 } 23 24 25 BEGIN_MESSAGE_MAP(CDllDialog, CDialog) 26 ON_BN_CLICKED(IDC_BUTTON_Hello, OnBnClickedButtonHello) 27 END_MESSAGE_MAP() 28 29 30 // CDllDialog message handlers 31 32 void CDllDialog::OnBnClickedButtonHello() 33 { 34 // TODO: Add your control notification handler code here 35 MessageBox("Hello!!!"); 36 }
4、添加脚本globla.cpp,代码如下:
1 #include "StdAfx.h" 2 #include "DllDialog.h" 3 4 extern "C" __declspec(dllexport) void ShowDlg(void) 5 { 6 CDllDialog dllDialog; 7 dllDialog.DoModal(); 8 }
5、此时编译会报error C2065: 'IDD_DLLDIALOG_TEST' : undeclared identifier错误,那是因为global.cpp中所引用的StdAfx.h未添加Resource.h资源:
1 #pragma once 2 3 #ifndef VC_EXTRALEAN 4 #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers 5 #endif 6 7 // Modify the following defines if you have to target a platform prior to the ones specified below. 8 // Refer to MSDN for the latest info on corresponding values for different platforms. 9 #ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later. 10 #define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. 11 #endif 12 13 #ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later. 14 #define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 2000 or later. 15 #endif 16 17 #ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. 18 #define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. 19 #endif 20 21 #ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later. 22 #define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later. 23 #endif 24 25 #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit 26 27 #include <afxwin.h> // MFC core and standard components 28 #include <afxext.h> // MFC extensions 29 30 #ifndef _AFX_NO_OLE_SUPPORT 31 #include <afxole.h> // MFC OLE classes 32 #include <afxodlgs.h> // MFC OLE dialog classes 33 #include <afxdisp.h> // MFC Automation classes 34 #endif // _AFX_NO_OLE_SUPPORT 35 36 #ifndef _AFX_NO_DB_SUPPORT 37 #include <afxdb.h> // MFC ODBC database classes 38 #endif // _AFX_NO_DB_SUPPORT 39 40 #ifndef _AFX_NO_DAO_SUPPORT 41 #include <afxdao.h> // MFC DAO database classes 42 #endif // _AFX_NO_DAO_SUPPORT 43 44 #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls 45 #ifndef _AFX_NO_AFXCMN_SUPPORT 46 #include <afxcmn.h> // MFC support for Windows Common Controls 47 48 #include "Resource.h" 49 #endif // _AFX_NO_AFXCMN_SUPPORT
6、build生成dllTest.dll文件
7、添加调用项目dllCall
8、切换到Resource View,增加Button(Caption:调用DLL):
9、点击进行Button进入dllCallDlg.cpp方法:增加代码如下:
1 void CdllCallDlg::OnBnClickedButton1() 2 { 3 typedef void (*lpFun)(void); 4 5 HINSTANCE hDll; //DLL句柄 6 hDll = LoadLibrary("..\\dllTest\\Debug\\dllTest.dll"); 7 if (NULL==hDll) 8 { 9 MessageBox("DLL加载失败"); 10 return; 11 } 12 13 lpFun addFun; //函数指针 14 lpFun pShowDlg = (lpFun)GetProcAddress(hDll,"ShowDlg"); 15 if (NULL==pShowDlg) 16 { 17 MessageBox("DLL中函数寻找失败"); 18 return; 19 } 20 pShowDlg(); 21 }
10、Ctrl+F5运行,后点击调用DLL却没响应。
11、分析后有两种方案可解决:
1)转换资源句柄,dllCallDlg.cpp代码修改如下:
特别说明:句柄的不同会导致最终弹出的对话框的标题不同。
1 void CdllCallDlg::OnBnClickedButton1() 2 { 3 typedef void (*lpFun)(void); 4 5 HINSTANCE hDll; //DLL句柄 6 hDll = LoadLibrary("..\\dllTest\\Debug\\dllTest.dll"); 7 if (NULL==hDll) 8 { 9 MessageBox("DLL加载失败"); 10 return; 11 } 12 13 lpFun addFun; //函数指针 14 lpFun pShowDlg = (lpFun)GetProcAddress(hDll,"ShowDlg"); 15 if (NULL==pShowDlg) 16 { 17 MessageBox("DLL中函数寻找失败"); 18 return; 19 } 20 HINSTANCE hOld = AfxGetResourceHandle(); 21 AfxSetResourceHandle(hDll); 22 pShowDlg(); 23 AfxSetResourceHandle(hOld); 24 }
2)、更改mfc使用模式:
右击项目dllTest,选择propert,发现use of mfc选择是Use MFC in a Shared DLL,将其更改为Use MFC in a Static Library,保存重新build即可。
特别说明:
use of mfc选项的区别:
Use Standard Windows Libraries:不用MFC类,就是说,如果你选择这项,而且的你的代码中存在MFC类的话,编译应该是不通过的。
Use MFC in a Static Library:静态链接。编译后的程序直接包含了调用MFC的库,这样文件会大一些,但是可以直接转移到其他电脑上运行。它发布时程序不用带MFC的dll。
Use MFC in a Static Library:动态链接。编译后的程序不包含MFC库,所以文件比较小,但是如果把程序直接转移到一个没安装MFC的电脑上,可能会因为找不到MFC的dll而编译不通过。它发布时需要带MFC的dll。