Click here to Skip to main content
15,443,778 members
Articles / Desktop Programming / MFC
Posted 25 Jun 2000


89 bookmarked

Dll Tips

Rate me:
Please Sign up or sign in to vote.
4.48/5 (16 votes)
4 Oct 2000
Tips for writting Dynamic Link Libraries

Dynamic Link Libraries using with MFC

This document is intended to give a beginner knowledge that may be helpful when designing a project for the Windows platform. When I start a new project I try to put all code that has the greatest chance of changing into a DLL. This provides the ability to make updates to the project without having to recompile every piece. This allows for a minimum piece of code to be redistributed.

For this to work properly, there are some tips that must be followed. Much of you are asking “Why this @$&^# doesn’t use COM ?”. Of course COM is a good choice, but I’m here to show another way. Some of this code looks like COM (of course I use it’s architecture!!).

The problem with DLL’s (specially those that use MFC) is that the debug and release versions are incompatible. You have probably seen this when running a debug application version with the DLL release version. The whole world gets crazy!! The best way, in fact the way Microsoft does it, is to give different names to the different builds of the DLL. The release build of the DLL uses the [Project Name].DLL format while the debug version will use the [Project Name]D.DLL format. Note the "D" after the project name. Using this approach allows you to send the two DLLs to the installation directory with an application build and the application will work properly.

Example: Naming convention for different builds of the same DLL

These are the steps needed to achieve this (Assume the project name is AAA):

  1. Copy the AAA.def to AAAD.def and change all the AAA occurrences to AAAD.
  2. In the Project/Settings dialog, select Win32 Debug Build.
  3. Under the tab Link change the Output file name to AAAD.DLL.
  4. At the bottom of the property page you will see something like:
    /def:".\AAA.def" /out:"Debug/AAAD.DLL"
    Change to:
    /def:".\AAAD.def" /out:"Debug/AAAD.DLL"
  5. Now the debug version will create AAAD.lib and AAAD.DLL files.

When I create a DLL, I create an include header for it (I think everybody does), which I named DLL header. This header has all the exported class definitions. And to be more efficient I include the linking stuff in this file also. I would do this so you do not have to add the lib file to the Project Settings. My header looks like:


#ifdef _DEBUG
#pragma comment(lib, AAAD.lib)
#pragma comment(lib, AAA.lib)

... the class definitions go here



The preferred kind of DLL used to export classes is a MFC extension DLL. By using this you can easily instantiate a class that is within a DLL. To do this you just declare the class as follows:



Evolving Implementations

In the application that uses this class you need to include the DLL header and everything is cool. The problem is: every time you need to include a member variable or a method to an exported class you have to change the DLL header. This means that every component that uses the dll must be recompiled. For new methods I don’t know a way to overcome this recompilation problem, but for new variables there’s a workaround.

Example: Handling Evolving Data Member Implmentation

Instead of declaring the member variables directly in the class body, you create a kind of implementation class, like the sample code:

class CFooImpl;
class CFoo

     CFooImpl* m_pThis;


The CFooImpl class doesn’t need to be exposed to the components that use the DLL. The implementation of CFooImpl would look like:

class CFooImpl
    CString m_sName;


    m_pThis = new CFooImpl;
    m_pThis->m_sName = _T("Unknown");

    delete m_pThis;

Evolving Data Structures

Another way to prepare for changes is to use intelligent structs the way that the Windows API does. You declare a method that has an LPVOID as in and out parameter. These pointers are address of struct instances. The trick is to define the first struct a member of DWORD type to hold it’s size. This way you can determine which data is available in the struct.

Example: Evolving Data Structures

typedef struct tagCHANGEABLE
     DWORD dwSize;
     long lBytes;

BOOL CFoo::Method(LPVOID lpIn)
     LPCHANGEABLE lpChangeable = (LPCHANGEABLE)lpIn;

     if (lpChangeable->dwSize == sizeof(CHANGEABLE))
         return TRUE;
     return FALSE;

Using it:

CFoo myFoo;

CHANGEABLE changeable;
memset(&changeable, 0, sizeof(changeable));

changeable.dwSize = sizeof(changeable);



Sometimes you have situations that requires you to call a dialog or create a class instance. So you decide to put those items in a DLL, but you don’t want the DLL to be loaded when the application gets executed. You want to load the DLL when needed (COM). This kind of DLL I call Dynamic DLL (stupid name I know “Dynamic Dynamic link libraries”).

Example: Loading A DLL As Needed

So you declare the exported function as:

__declspec( DLLexport )
void MyExportedFunc(DWORD dw)

We need to include this function in the def files (debug and release). The debug def file would look like this:

; AAAD.def : Declares the module parameters for the DLL.


DESCRIPTION  'AAAD Windows Dynamic Link Library'

    MyExportedFunc @1
    ; Explicit exports can go here

Now to use this function we need to load the library, find the function entry point and call it.

typedef void (*MYFUNC)(DWORD);  

#ifdef _DEBUG
    HINSTANCE hDLL = AfxLoadLibrary("AAADLLD");
    HINSTANCE hDLL = AfxLoadLibrary("AAADLL");

    if (hDLL)
        FARPROC pnProc = GetProcAddress(hDLL, "MyExportedFunc");
        MYFUNC pnMyfunc = (MYFUNC)pnProc;



Remember that to show a dialog you must take care of the resource stuff (AfxSetResource..). You can also use this approach to create class instances. The class definition must use pure virtual functions (to avoid an unresolved external symbol). This is just like COM.
The class definition should look like this:

class CFoo
   virtual void Initialize (CString sName) = 0;

You implement this “interface” with another class that is not visible through the DLL header file.

class CFooImp  : public CFoo
    virtual ~CFooImp();

    void Initialize (CString sName)
        m_sName  = sName;

    CString m_sName;

To create an instance of this class (interface) you create an exported function.


CFoo* CreateFoo(DWORD dwVersion)
     if (dwVersion == CURRENT_VERSION)
        return new CFooImp;

     return NULL;

The application creates the class instance like this:

typedef CFoo* (*MYFUNC)(DWORD);  

#ifdef _DEBUG
    HINSTANCE hDLL = AfxLoadLibrary("AAADLLD");
    HINSTANCE hDLL = AfxLoadLibrary("AAADLL");

    if (hDLL)
        FARPROC pnProc = GetProcAddress(hDLL, " CreateFoo");
        MYFUNC pnMyfunc = (MYFUNC)pnProc;

        CFoo* pFoo = pnMyfunc(0);


        delete pFoo;

Remember that you cannot free the library that contains the CFoo implementation until you have deleted the CFoo instance.


These examples explain the powers of well-designed DLLs. A good design is the first and most important step to the successful project. Unfortunately, if the whole project has a poor design no miracle will make your applications easy to change and update.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Written By
Architect VisionOne AG
Switzerland Switzerland
XicoLoko is a brazilian developer based in Switzerland.

Comments and Discussions

QuestionCall VC++ dll from Javascipts Pin
zaiyatul hijah13-Aug-07 23:31
Memberzaiyatul hijah13-Aug-07 23:31 
Generalnice one Pin
f214-Jul-06 9:32
Memberf214-Jul-06 9:32 
GeneralDiplaying dialog from a dll Pin
Anonymous19-Jan-04 23:54
MemberAnonymous19-Jan-04 23:54 
Generalregd dll for winamp Pin
karteek2-Dec-03 1:07
Memberkarteek2-Dec-03 1:07 
Generalregd dll for winamp Pin
karteek2-Dec-03 1:05
Memberkarteek2-Dec-03 1:05 
QuestionLoad the correct dll ? Pin
Timbavati24-Sep-03 6:03
MemberTimbavati24-Sep-03 6:03 
GeneralAbout Load dialog from a DLL Pin
William GS20-Sep-03 5:02
MemberWilliam GS20-Sep-03 5:02 
GeneralExtension DLL - Explicit Linking problem Pin
Anonymous30-Jul-03 21:28
MemberAnonymous30-Jul-03 21:28 
GeneralRe: Extension DLL - Explicit Linking problem Pin
xicoloko31-Jul-03 0:23
Memberxicoloko31-Jul-03 0:23 
GeneralRe: Extension DLL - Explicit Linking problem Pin
Anonymous31-Jul-03 19:21
MemberAnonymous31-Jul-03 19:21 
GeneralExtension DLL - Explicit Linking GetProcAddress returns NULL Pin
rabbitkn10-Mar-04 20:18
Memberrabbitkn10-Mar-04 20:18 
Generalinterfacing a dll with multithreaded application Pin
nishi_prasu26-Mar-03 23:14
Membernishi_prasu26-Mar-03 23:14 
GeneralDLL X-Files Pin
gregsan10-Aug-02 23:42
Membergregsan10-Aug-02 23:42 
GeneralDLLS creation Pin
24-Mar-02 1:43
suss24-Mar-02 1:43 
Generalrun a DLL from another EXE Pin
Impact23-Jan-02 4:10
MemberImpact23-Jan-02 4:10 
GeneralRe: run a DLL from another EXE Pin
xicoloko23-Jan-02 4:32
Memberxicoloko23-Jan-02 4:32 
GeneralRe: run a DLL from another EXE Pin
Impact23-Jan-02 14:10
MemberImpact23-Jan-02 14:10 
GeneralRe: run a DLL from another EXE Pin
xicoloko24-Jan-02 4:34
Memberxicoloko24-Jan-02 4:34 
GeneralRe: run a DLL from another EXE Pin
Impact28-Jan-02 14:07
MemberImpact28-Jan-02 14:07 
GeneralRe: run a DLL from another EXE Pin
Carlos Antollini23-Jan-02 4:40
MemberCarlos Antollini23-Jan-02 4:40 
GeneralAdding a dialog into dll, classwizard doesn't add *** line Pin
1-Jan-02 3:57
suss1-Jan-02 3:57 
GeneralRe: Adding a dialog into dll, classwizard doesn't add *** line Pin
Atul G. Katti8-Apr-02 19:20
MemberAtul G. Katti8-Apr-02 19:20 
GeneralRe: Adding a dialog into dll, classwizard doesn't add *** line Pin
Rick Crone27-Jun-02 3:48
MemberRick Crone27-Jun-02 3:48 
GeneralRe: Adding a dialog into dll, classwizard doesn't add *** line Pin
Atul G. Katti2-Jul-02 19:26
MemberAtul G. Katti2-Jul-02 19:26 
GeneralRe: Adding a dialog into dll, classwizard doesn't add *** line Pin
Rick Crone3-Jul-02 3:01
MemberRick Crone3-Jul-02 3:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.