我写了个DLL,里面封装了一个对话框,Settings中设的是Use MFC in a Static Library,再用这个DLL时出现了这样的问题,就是程序退出时崩溃,在CWnd::~CWnd中,不知是什么缘故,设成Use MFC in a Shared DLL没有这样的问题。
解决方案 »
- 一个很奇怪的问题
- 求BMP数据块部分的解码和压缩函数
- richedit的findtext怎么一直返回-1
- 菜鸟问题! 请问如何在程序中设置和菜单的DISABLE,ENABLE属性
- 如何学习direct游戏编程,指导一下的请进~~
- 请教大侠:怎样用VC播放一个.WAV文件?
- 为什么我编译后的执行文件不执行?
- VC中编译通过的project,为什么classview视图中缺少了一些类?这些类有定义,也有被调用。
- CString str="20010921";哦如何把它副职给COleDateTime,和SYSTEMTIME tm
- 我还是有问题没弄明白,大虾请看看!witsoft2000(witsoft2000)也快看看呀!!!
- 有关头文件的问题!!
- 如何实现在编辑框中按下回车光标进入下一编辑框
1、在向导中点MFC AppWizard(dll),生成一个支持MFC的DLL。
2、在DLL中添加一个对话框资源。
3、给对话框对应一个类m_MyDlg。
4、在CXXXApp中添加InitInstance(),并在其中加一句
m_MyDlg.Create(IDD_DIALOG1);
5、添加一个全局的函数
int ShowDlg()
{
m_MyDlg.ShowWindow(SW_SHOW);
return 0;
}
6、在.def文件中导出ShowDlg
7、编译,连接,将生成的.dll和.lib考入我的测试程序目录中。
8、我在测试程序中添加这样的代码: #pragma comment(lib, "Dlg") int ShowDlg(); void CTestDlg::OnButton1()
{
ShowDlg();
}
----------------------------
现象:
1、点击测试程序中的Button1可以弹出对话框。
2、退出时红叉出现。定位进程序,堆栈是这样的:CMapPtrToPtr::GetValueAt(void * 0x0007085e) line 179 + 3 bytes
CHandleMap::LookupPermanent(void * 0x0007085e) line 90 + 22 bytes
CWnd::DestroyWindow() line 959 + 15 bytes
CDialog::~CDialog() line 159
CMyDlg::~CMyDlg() + 37 bytes
$E276() + 34 bytes
doexit(int 0x00000000, int 0x00000000, int 0x00000001) line 353
_cexit() line 294 + 11 bytes
_CRT_INIT(void * 0x10000000, unsigned long 0x00000000, void * 0x00000001) line 157
_DllMainCRTStartup(void * 0x10000000, unsigned long 0x00000000, void * 0x00000001) line 252 + 17 bytes
NTDLL! 77f83c48()
NTDLL! 77f8c4d4()
KERNEL32! 77e7b110()
doexit(int 0x00000002, int 0x00000000, int 0x00000000) line 392
exit(int 0x00000002) line 279 + 13 bytes
WinMainCRTStartup() line 212
KERNEL32! 77e67903()---------------------------------
按照我所说的步骤,改过程可以重现,前提是 Use MFC in a Static Library 。谁知道个中理由,分不够可以再加。
3、给对话框对应一个类m_MyDlg。
应该是:
3、给对话框对应一个类CMyDlg。m_MyDlg 被我设成了全局的,我名字起得不好,属笔误。
Regular DLL中的哪种?
是不是动态链接到MFC的规则DLL?
还是Extension DLL~
不是Extension DLL
Regular DLL using Shared MFC DLL
我刚试过,用Regular DLL with MFC staticlly linked也不行
试过了,不行呀!
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CCMyDlg m_MyDlg;
m_MyDlg.DoModal();
return 0;
}去掉m_MyDlg这个全局变量,或者你用指针
解决了没有呀?
我也遇到相同的问题了
We've been looking at Win32 DLLs that have a DllMain function and some exported functions. Now we'll move into the world of the MFC application framework, which adds its own support layer on top of the Win32 basics. AppWizard lets you build two kinds of DLLs with MFC library support: extension DLLs and regular DLLs. You must understand the differences between these two types before you decide which one is best for your needs.
Of course, Visual C++ lets you build a pure Win32 DLL without the MFC library, just as it lets you build a Windows program without the MFC library. This is an MFC-oriented book, however, so we'll ignore the Win32 option here.An extension DLL supports a C++ interface. In other words, the DLL can export whole classes and the client can construct objects of those classes or derive classes from them. An extension DLL dynamically links to the code in the DLL version of the MFC library. Therefore, an extension DLL requires that your client program be dynamically linked to the MFC library (the AppWizard default) and that both the client program and the extension DLL be synchronized to the same version of the MFC DLLs (mfc42.dll, mfc42d.dll, and so on). Extension DLLs are quite small; you can build a simple extension DLL with a size of 10 KB, which loads quickly. If you need a DLL that can be loaded by any Win32 programming environment (including Visual Basic version 6.0), you should use a regular DLL. A big restriction here is that the regular DLL can export only C-style functions. It can't export C++ classes, member functions, or overloaded functions because every C++ compiler has its own method of decorating names. You can, however, use C++ classes (and MFC library classes, in particular) inside your regular DLL. When you build an MFC regular DLL, you can choose to statically link or dynamically link to the MFC library. If you choose static linking, your DLL will include a copy of all the MFC library code it needs and will thus be self-contained. A typical Release-build statically linked regular DLL is about 144 KB in size. If you choose dynamic linking, the size drops to about 17 KB but you'll have to ensure that the proper MFC DLLs are present on the target machine. That's no problem if the client program is already dynamically linked to the same version of the MFC library. When you tell AppWizard what kind of DLL or EXE you want, compiler #define constants are set as shown in the following table. Dynamically Linked to Shared MFC Library Statically Linked* to MFC Library
Regular DLL _AFXDLL, _USRDLL _USRDLL
Extension DLL
_AFXEXT, _AFXDLL unsupported option
Client EXE _AFXDLL no constants defined
* Visual C++ Learning Edition does not support the static linking option. If you look inside the MFC source code and header files, you'll see a ton of #ifdef statements for these constants. This means that the library code is compiled quite differently depending on the kind of project you're producing. The Shared MFC DLLs and the Windows DLLs
If you build a Windows Debug target with the shared MFC DLL option, your program is dynamically linked to one or more of these (ANSI) MFC DLLs: mfc42d.dll Core MFC classes
mfco42d.dll ActiveX (OLE) classes
mfcd42d.dll Database classes (ODBC and DAO)
mfcn42d.dll Winsock, WinInet classes
When you build a Release target, your program is dynamically linked to mfc42.dll only. Linkage to these MFC DLLs is implicit via import libraries. You might assume implicit linkage to the ActiveX and ODBC DLLs in Windows, in which case you would expect all these DLLs to be linked to your Release-build client when it loads, regardless of whether it uses ActiveX or ODBC features. However, this is not what happens. Through some creative thunking, MFC loads the ActiveX and ODBC DLLs explicitly (by calling LoadLibrary) when one of their functions is first called. Your client application thus loads only the DLLs it needs. MFC Extension DLLs—Exporting Classes
If your extension DLL contains only exported C++ classes, you'll have an easy time building and using it. The steps for building the EX22A example show you how to tell AppWizard that you're building an extension DLL skeleton. That skeleton has only the DllMain function. You simply add your own C++ classes to the project. There's only one special thing you must do. You must add the macro AFX_EXT_CLASS to the class declaration, as shown here:
class AFX_EXT_CLASS CStudent : public CObject
This modification goes into the H file that's part of the DLL project, and it also goes into the H file that client programs use. In other words, the H files are exactly the same for both client and DLL. The macro generates different code depending on the situation—it exports the class in the DLL and imports the class in the client. The MFC Extension DLL Resource Search Sequence
If you build a dynamically linked MFC client application, many of the MFC library's standard resources (error message strings, print preview dialog templates, and so on) are stored in the MFC DLLs (mfc42.dll, mfco42.dll, and so on), but your application has its own resources too. When you call an MFC function such as CString::LoadString or CBitmap::LoadBitmap, the framework steps in and searches first the EXE file's resources and then the MFC DLL's resources. If your program includes an extension DLL and your EXE needs a resource, the search sequence is first the EXE file, then the extension DLL, and then the MFC DLLs. If you have a string resource ID, for example, that is unique among all resources, the MFC library will find it. If you have duplicate string IDs in your EXE file and your extension DLL file, the MFC library loads the string in the EXE file. If the extension DLL loads a resource, the sequence is first the extension DLL, then the MFC DLLs, and then the EXE. You can change the search sequence if you need to. Suppose you want your EXE code to search the extension DLL's resources first. Use code such as this:
HINSTANCE hInstResourceClient = AfxGetResourceHandle();
// Use DLL's instance handle
AfxSetResourceHandle(::GetModuleHandle("mydllname.dll"));
CString strRes;
strRes.LoadString(IDS_MYSTRING);
// Restore client's instance handle
AfxSetResourceHandle(hInstResourceClient);You can't use AfxGetInstanceHandle instead of ::GetModuleHandle. In an extension DLL, AfxGetInstanceHandle returns the EXE's instance handle, not the DLL's handle.