text: Dynamic Link Libraries With Microsoft Foundation, Just the Facts.
  The main purpose of this document is to provide a concise and simple explanation of how to build Dynamic Link Libraries (DLL) that contain dialog resources and use Microsoft Foundation Libraries (MFC). A simple example is used to illustrate some common pitfalls encountered in DLL development and some of the basic interaction between application and DLL.
  This article assumes some basic usage and understanding of building MFC applications using the Microsoft Developer Studio and Visual C++ 6.0.
  Keywords
  Dynamic Link Library, DLL, MFC, Assert, CWnd, compile, MSDN, errors, Microsoft Developer Studio, Visual C++ 6.0
  Introduction
  This project contains a sample application, MFCdll_demo.zip.
  The problems all began when I received the Developers Studio 6.0 and revisited a program that originated it's 32-bit days with Visual C++ 4.0. Compiling this old project and it's dependent DLLs no longer worked correctly. The culprit; the implementation of the DLLs. What I was attempting to do is not difficult in concept (I had already done this in the original version of the DLL) and is a very common with application development. The scenario is an application with two DLLs; one DLL containing a dialog box resource template and its class, and the other DLL contains basic functionality. The application and the second DLL need to be able to instantiate the dialog boxes contained in the first DLL. The problems here are created when dealing with regular DLLs, extension DLLs with MFC, exporting and importing functions, and managing the projects in the work space in such a way things compile and link fairly easily.
  The simplest method to explain this complication is to use an example project, which can be found in the zip file "MFCdll_demo.zip." The work space consists of four projects, TheApp, DllA, DllB, and DllC. The dependencies of the project are: TheApp depends on all three DLLs, DllA depends on DllB, DllB has no dependencies, and DllC depends on the other two, DllA and DllB. Each of the DLLs were created with the AppWizard(DLL) with DllA as an Extension DLL using shared MFC DLL, DllB a MFC Extension DLL, and DllC is a Regular DLL. These terms refer to the options available during the AppWizard setup of a DLL as shown in Figure 1.
  Figure 1. MFC DLL App Wizard
  Now here is where a lot of confusion may occur. A extension DLL as described by the label in the AppWizard contains the dll entry point function DllMain(). Code created for the DllA in the file DllA.CPP is shown below.
  static AFX_EXTENSION_MODULE DllADLL = {("DLLA.DLL Initializing!\n"); // Extension DLL one-time initialization if (!AfxInitExtensionModule(DllADLL, hInstance)) return 0; // Insert this DLL into the resource chain // NOTE: If this Extension DLL is being implicitly linked to by // an MFC Regular DLL (such as an ActiveX Control) // instead of an MFC application, then you will want to // remove this line from DllMain and put it in a separate // function exported from this Extension DLL. The Regular DLL // that uses this Extension DLL should then explicitly call that // function to initialize this Extension DLL. Otherwise, // the CDynLinkLibrary object will not be attached to the // Regular DLL's resource chain, and serious problems will // result. new CDynLinkLibrary(DllADLL); } else if (dwReason == DLL_PROCESS_DETACH) { TRACE0("DLLA.DLL Terminating!\n"); // Terminate the library before destructors are called AfxTermExtensionModule(DllADLL); } return 1; // ok }
  A Regular DLL on the other had does not create a DllMain(), but instead creates a CWinApp class which looks like the following code fragment taken from the DLLC.CPP file.
  ///////////////////////////////////////////////////////////////////////////// // CDllCApp BEGIN_MESSAGE_MAP(CDllCApp, CWinApp) //{{AFX_MSG_MAP(CDllCApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDllCApp construction CDllCApp::CDllCApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } ///////////////////////////////////////////////////////////////////////////// // The one and only CDllCApp object CDllCApp theApp;
  In the example used here, DllB is initially defined to be a Regular DLL which has code similar to the above segment.
  No problem so far. However, looking at the documentation in the MSDN library you will find Technical Article 33, "TN033: DLL Version of MFC" which has the following two bullets:
  Since an extension DLL does not have a CWinApp and a Regular DLL does, when working with both types it is very easy to get confused. If an Regular DLL has the CWinApp class removed, your program will not work and you will end up getting an assert when your dialog box attempts to set up its message pump.Another distinction between the two DLL types is in the preprocessor directives. For the DLL (DllC) you will notice two definitions, _AFXDLL and _USRDLL. An important distinction between the Regular and Extension DLL is the inclusion of the _USRDLL preprocessor definition. An Extension DLL does not define the _USRDLL definition.
  To further confuse this issue there are MFC bugs and MSDN documentation errors (see references). To help clarify some of these potential problems we will examine the project TheApp. This project has a DLLs each containing a simple dialog box. The dependencies are illustrated in Figure 2.
  Figure 2. TheApp Project Dependencies
  The three DLLs contain a simple dialog box, each created using the resource editor and class wizards in the Developer Studio. Two of the dialogs, DllA and DllC have buttons to activate the other dialogs, whereas DialogB only contains an edit box to display text. All three dialogs are illustrated in figures 3 through 5.
  Figure 3. Dialog A
  Figure 4. Dialog A
  Figure 5. Dialog A
  With everything created let us take at look at the document class for TheApp. Starting very simply we will have CTheAppDoc call all three of the dialog boxes using various methods. In order for the dialogs to be called the appropriate information must be imported from the appropriate DLL. More on Import/Export concepts later. There are two methods for calling DialogA. The first uses the exported function
  int ShowDialogA( CString& text );
  The advantage here is that the calling program does not need to have the CDialogA class defined, which also means you do not need to know anything about the resource ID for that dialog. The only thing that needs to be exported from the DllA is the above function. The implementation of this exported function is very simple and is a basic usage of a dialog object.
  DLGAPorting int ShowDialogA( CString& text ) { CDialogA dlg; dlg.m_sEdit = text; int nReturn = dlg.DoModal(); if ( nReturn = IDOK ) text = dlg.m_sEdit; return nReturn; }
  The second method is to use the CDialogA class directly, as is typically done. The only trick here is to export CDialogA from the DLL and import it into the document class. Here is the code that implements these two methods.
  void CTheAppDoc::OnDialogsDialoga() { // This function does not need to have the CDialogA class exported, only // will need to see the ShowDialogA function exported from the dll. CString sTheText = "Text String Stating in DialogA."; ShowDialogA( sTheText ); // It should be different now if the user changed it. } void CTheAppDoc::OnDialogsDialoga2() { CDialogA dlg; dlg.m_sEdit = "Text String Stating in DialogA using method 2."; // Typical Dialog usage can be done here. dlg.DoModal(); }
  Next, for the document to open up CDialogB which is defined in the DllB DLL, the user may again use the same procedure as above and call the int ShowDialogB(CString& s) function. This method works perfectly well with a couple of provisions not needed for the CDialogA. Looking at the implementation of the ShowDialogB() one can see a couple of differences.
  int ShowDialogB( CString& text ) { // Removing the following line will cause an First chance // Exception during runtime when you call this function. AFX_MANAGE_STATE(AfxGetStaticModuleState()); // If you use the following line of code you will get an assertation // on line 884 of WinCore.CPP in the CWnd::AssertValid() function // in debug mode // CDialogB dlg; // The work around is CDialogB dlg( AfxGetMainWnd() ); dlg.m_sText = text; int nReturn = dlg.DoModal(); if ( nReturn = IDOK ) text = dlg.m_sText; return nReturn; }
  In order to prevent a debug assert in the WinCore.cpp file you need to add the macro AFX_MANAGE_STATE( AfxGetStaticModuleState() ) as the first command in the function. Also, the CWnd* parameter for the CDialog constructor needs to be assigned with the function AfxGetMainWnd(). This is discussed in more detail in the MS technical article Q194300.
  Now, there is one pitfall here to be aware of; do not add this code to the implementation of the ShowDialogA() function. Doing so will give you linker errors that look like the following.
  mfcs42d.lib(dllmodul.obj) : error LNK2005: __pRawDllMain already defined in DllA.obj mfcs42d.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in DllA.obj mfcs42d.lib(dllmodul.obj) : error LNK2005: __pRawDllMain already defined in DllA.obj mfcs42d.lib(dllmodul.obj) : warning LNK4006: _DllMain@12 already defined in DllA.obj; second definition ignored mfcs42d.lib(dllmodul.obj) : warning LNK4006: __pRawDllMain already defined in DllA.obj; second definition ignored
  For the CDialogA class, there is a second method of implementing the dialog by using the dialog class directly exported from the DLL. Note however, that this does not work with the Regular DLL. This does not work because dialog object is unable to locate its resource template when the DoModal() function is called. Now the astute programmer would say, "Well, why not overload the DoModal() function in the CDialogA class and add the AFX_MANAGE_STATE( AfxGetStaticModuleState() ) macro at the beginning of the function." It is a good suggestion, one which I believe worked in previous versions of Visual C++, but now prone to problems. Executing such a program will cause runtime asserts in the CWnd::AssertValid() function which are discussed in detail in MS technical article Q194300. The only solution I found was to use the implementation mentioned above. The code segment below illustrates problematic code.
  void CTheAppDoc::OnDialogsDialogb2() { // This implementation of using the actual dialog fails. The reason // is in the attempt to locate the resource template for the dialog // in the DLL. CDialogB dlg; dlg.m_sText = "Text String Stating in DialogB using method 2."; // Typical Dialog usage can be done here. dlg.DoModal(); // Display a message telling the user that their attempt to // display the dialog box failed. AfxMessageBox( "This Calling method compiles but fails." ); } int CDialogB::DoModal() { // Putting this code here will cause an Assert in the CWnd::AssertValid() // AFX_MANAGE_STATE(AfxGetStaticModuleState()); return CDialog::DoModal(); }
  Finally, the last dialog box in the DllC.DLL, CDialogC, is the same as CDialogB and must follow the same rules. For the sake of completeness, here is its calling code.
  void CTheAppDoc::OnDialogsDialogc() { CString text = "Text String Stating in DialogC"; ShowDialogC( text ); }
  The next issue involving DLLs and dialog boxes, involves a DLL invoking a dialog which is located in a different DLL. There are four calling possibilities: 1. Regular calling and Regular DLL, 2. An Extension calling and Regular DLL, 3. A Regular calling an Extension DLL, 4. Extension calling a Extension DLL. The fourth calling method is not directly implemented in the sample program TheApp. However, a good exercise is to change CDialogB from an Extension DLL to a Regular DLL to test CDialogA calling CDialogB when both are regular DLLs.
  In the first implementation with an Regular DLL calling an another Regular DLL there is really no surprise. Since it is difficult to export the dialog class, the calling is done through the helper functions I created in the exports, ShowDialogB(). Here CDialogC initiates CDialogB.
  void CDialogC::OnButtonb() { UpdateData(); if ( ShowDialogB( m_sText ) == IDOK ) UpdateData(FALSE); }
  The second possibility is an Extension DLL calling an Regular DLL. Again this is pretty straight forward for the reasons mentioned above. The code for the CDialogA calling CDialogB is the nearly the same.
  void CDialogA::OnButtonb() { UpdateData(); if ( ShowDialogB( m_sEdit ) == IDOK ) UpdateData(FALSE); }
  The third case, however, will cause a problem. Attempting to have a Regular DLL call a dialog in an Extension DLL cannot easily be accomplished, if at all. The following code segment demonstrates this problem.
  void CDialogC::OnButtona() { // if I tried to do this I get an Assert in the CWnd::AssertValid() // Function. /* CDialogC dlg; dlg.DoModal(); */ // and this method does not crash, but there is a first chance exception // error but the program does not halt. UpdateData(); if ( ShowDialogA( m_sText ) == IDOK ) UpdateData(FALSE); }
  There are a couple indications that you would see if you tried to make this happen. Trying to use the ShowDialogA( m_sText ) call will compile and run, but you will get a trace error that gives you a first chance exception error when the DoModal() call is made. Attempting to use the dialog class to create the dialog will also compile and run, but will give you an assert in the CWnd::AssertValid() function. I have no solution for this situation and I will defer details of the problem to the MSDN references.
  The final combination is a regular DLL calling a dialog in another regular DLL. In this case either of the discussed methods will work. Either use the calling function ShowDialogB(), or using the dialog class directly. To test this all that needs to be done is to convert DllB to a regular DLL from a externsion DLL. This can easily be done by making a couple of simple code modifications. In the example files DllB.cpp and DllB.h are #ifndef B_IS_REGULAR statements to simplify the conversion. Open up the project settings for the DllB project and edit the pre-processor definitions as shown in Figure 6.
  Figure 6. DllB Compiler Settings
  The preprocessor definitions when the DLL is an Extension DLL should be
  _DEBUG, WIN32, _WINDOWS,_WINDLL,_AFXDLL,_MBCS,_AFXEXT, COMPILING_DLL
  nd when the DLL is a Regular DLL
  _DEBUG,WIN32,_WINDOWS,_WINDLL,_AFXDLL,_MBCS,_AFXEXT, COMPILING_DLLB,_USRDLL, B_IS_REGULAR
  When B_IS_REGULAR is defined and _USRDLL is not defined the DLL will be a regular DLL. When B_IS_REGULAR is not defined and _USRDLL is define the DLL will be an extension DLL. I will leave it to the reader examine the code differences. The real key here is the _USERDLL definition.
  To help assist the reader in making the conversion the preprocessor key B_IS_REGULAR has been created. This key changes what code is included when compiling the DLL and separates the code difference between an extension and regular DLL. Basically, changes the usage of a DllMain() entry point function or a CWinApp class existence in the DLL. Also, removes or adds the AFX_MANAGE_STATE(AfxGetStaticModuleState()) macro when necessary.
  A final item to contend with in the conversion of the DLL is how the function is called from the CDialogA button. The button handler function should be modified to the following.
  void CDialogA::OnButtonb() { // use this block for the Extension DLL { /* UpdateData(); if ( ShowDialogB( m_sEdit ) == IDOK ) UpdateData(FALSE); */ } // Use this block of code for a regular DLL { CDialogB dlg; dlg.m_sText = m_sEdit; if ( dlg.DoModal() == IDOK ) { m_sEdit = dlg.m_sText; UpdateData(FALSE); } } }
  This concludes the discussion about the implementation of the different DLL types and how to interact dialogs between them.
  Additional Tips
  Using Batch Files
  When working with DLLs it is very useful to include the DLL project in the workspace for the dependant application. This way you can set up the dependencies which will link the required libraries. However, when you attempt to run the application the program will not be able to locate the DLL. This is basically a search path problem and there are several ways to work around this. The method I prefer is to take advantage of the Post Build commands. Simply make a batch file that will copy the successfully compiled DLL to the appropriate directory for your application. For example, I use the following batch file for the DllA project.
  DllBd.bat copy ..\DllA\Debug\*.dll ..\Debug
  When the DLL is done compiling it copies the DLL to the debug directory of the application that will be using it. Likewise I have a similar batch file for the release mode, and for the other DLLs.
  Handling Exports and Imports
  There are many possible methods for implementing the imports and exports of a DLL. The method I prefer is to use the #defines to indicate if the class or functions are being imported or exported. Using the .def file during development can be troublesome, however, there are some benefits for a library nearing final release. The nice feature of using the #define's is the same header files used for exporting the functions, can also be linked to the projects that are importing the functions. Technical Article 33 describes a similar process using the AFX_EXT_CLASS macro.
  In your preprocessor definitions for the DLL define a unique string; for DllA the string COMPILING_DLLA was used. Then in the header files where you need to export functions include the following code:
  // This is a little error checking to verify I only define this once #ifdef DLGAPorting #pragma message( "Warning! DLGAPorting already defined!" ) #undef DLGAPorting #endif #ifdef COMPILING_DLLA #define DLGAPorting __declspec( dllexport ) #pragma message( " Exporting DllA" ) #else #define DLGAPorting __declspec( dllimport ) #pragma message( " Importing DllA" ) #endif
  This is a pretty simple and efficient method of handling imports and exports. There are many other methods and this is only one of them. The choice is ultimately the programmers.
  Debugging
  One simple tip for debugging a DLL that is quite obvious once you have done it, however, until that point you might seem a bit lost. After compiling your new DLL in debug mode and attempt to execute the DLL you will receive a dialog box asking for an executable that for the library. In this box simple reference a application (.EXE) that uses your newly compiled DLL. You will then be able to debug your functions when they are called.
  This is especially useful for add-in DLLs. For example, Developer Studio Add-in DLLs. After creating your DLL, and you would like to debug it, specify the MSDEV.EXE as the executable for your DLL. When you start the debugger a second instance of MSDEV will start using your DLL giving you the ability to debug it.
  MSDN References:
  About The Author
  Christopher A. Snyder has a Master of Science in Electrical Engineering from Ohio University and is currently working as a research engineer at the Ohio University Avionics Engineering Center.Chris's home page can be found at
  DemoDownload demo project - 127 KB
  Date Last Updated: May 17, 1999
  The Secret master the nike-arena Is Pretty Simple!Posted by Acuddence on 05/04/2013 04:05am
  Fresh new questions about nike addressed and as a consequence the reasons you have to take a look at each and every concept on this insider report.[url=]nike ã´ã«ã[/url] A double strain on nike [url=-ã´ã«ããã¼ã«-c-23.html]nike ãã¼ã«[/url] Hot questions on nike addressed in addition to the reasons you would need to read through each and every statement within this documentation. [url=-ã¢ã¤ã¢ã³-c-1.html]nike ã´ã«ã[/url] Third party statement brings out Seven fresh, new things concerning mizuno that absolutely no one is speaking about. [url=-ã¢ã¤ã¢ã³-c-1.html]ãã¤ã[/url] All mizuno Service Speak - Workers who cares about zero triumphs?? [url=-ã´ã«ãã·ã¥ã¼ãº-c-15.html]nike air jordan[/url] Things and manufacturing throughout Las Vegas, Nevada - - nike actually leaves with no good-bye [url=]ãã¤ã[/url] Resources and processing in Las Vegas, Nevada : nike has left without goodbye [url=ãã¤ãRunning-c-3.html]nike running[/url] I would say the mizuno Enterprise Dialog - - The Ones Who cares about nada wins?!? [url=ãã¤ãDunk-c-9.html]nike dunk[/url] The mizuno Marketing Dialog : Customers who cares about nothing triumphs?? [url=ãã¤ãDunk-c-9.html]nike dunk[/url] mizuno will give all new lifespan for an old challenge: golden customaryReply
  The Secret master the mizuno-scene Is Really Straightforward!Posted by Acuddence on 04/27/2013 04:38pm
  Hot questions regarding nike replied to and consequently the reason why you must definitely start reading each concept of this documentation.[url=]ãã¤ãã´ã«ã[/url] An explicit double twirl on nike [url=-ã´ã«ããã¼ã«-c-23.html]ãã¤ã ãã¼ã«[/url] Recent questions on nike clarified and as a consequence the reasons you must absolutely read each concept of this report. [url=-ã¢ã¤ã¢ã³-c-1.html]ãã¤ã[/url] Neutral blog post unwraps Some fresh new stuff concerning nike that none is discussing. [url=-ã¢ã¤ã¢ã³-c-1.html]ãã¤ãã´ã«ã[/url] I would say the mizuno Company Talk - Who likes nada wins? [url=-ã´ã«ãã·ã¥ã¼ãº-c-15.html]nike air force 1[/url] Items and end production in Sin City - - nike will leave without thanks [url=]nike[/url] Appliances and end production in Nevada - nike simply leaves with no good-bye [url=ãã¤ãRunning-c-3.html]nike ã©ã³ãã³ã°[/url] All nike Business venture Presentation - Buyers who cares for absolutely nothing benefits?? [url=ãã¤ãDunk-c-9.html]ãã¤ã·ã¥ã¼ãº[/url] Often the mizuno Sector Call : Those who cares about stresses is successful?? [url=ãã¤ãDunk-c-9.html]nike dunk[/url] mizuno adds spanking new life span into an old subject-- silver customaryReply
  Michael Zimmerman PrenticePosted by ReotheUpsedsmoro on 03/19/2013 08:56am
  Many Hedge finances have got significant investments throughout investments that might lead them to slide within the definition connected with Investment decision Business within the Expenditure Corporation Act 1940 (Investment Act). However, Hedge Finances commonly make use of 1 of 2 statutory relegations from your definition involving "Investment Company" which makes it possible for them to steer clear of the regulating convention with the Expenditure Behave. [url= ]michael zimmerman prentice [/url] ExitsReply
  Ezima UgwuPosted by Ezima Ugwu on 10/10/2011 11:21am
  Anybody has any idea why attempt to create a modal dialog in a C++ dll (regular or extension) fails in Premodal() when called fom a VB application It succeeds when called from C++ application. Any help will greatly appreciated. email for possible answer ezima.ugwu@gmail.com Thanks Ezima Ugwu.Reply
  memory leaksPosted by miguelr on 03/26/2005 01:55pm
  Cannot execute programPosted by Legacy on 11/12/2003 12:00am
  Originally posted by: Murray King
  DLL with libPosted by Legacy on 05/19/2003 12:00am
  Originally posted by: Chuck
  I am including an external library as part of the dll build and want to export the data items in this library through the dll. Do I use an extern with the declspec directive and what is the ___imp_ preceeding the data names from this library on a dumpbin? Do I need to dereference these items as pointers or just do an import in the application with an extern to use? HELP! Thanks.Reply
  Problem with creating a libraryPosted by Legacy on 03/28/2003 12:00am
  Originally posted by: Harry
  I am trying to create a library with reference from a book but there always seems to be an error
  Reply
  Very good article - simple and understandingPosted by Legacy on 01/30/2003 12:00am
  Originally posted by: Joju Joseph
  How to access callig classPosted by Legacy on 07/25/2002 12:00am
  Originally posted by: Rabentochter
  Is it possible to access the class loading the DLL from within the DLL? If so, how can it be done? I'd be happy to get some helping hints! Thank you.Reply