Click here to Skip to main content
Click here to Skip to main content
Go to top

Creating and consuming MFC DLLs for Beginners

, 18 Aug 2012
Rate this:
Please Sign up or sign in to vote.
The objective of this tutorial is to demonstrate in a step by step manner how to build and call methods present in a DLL using Visual C++ 6.0. We are going to develop a DLL that takes in a string as input parameter and returns the string prefixed with a "Hello".

Sample Image

Introduction

What is a DLL? DLL stands for Dynamic Link Library. Using DLL's offers several advantages as mentioned below:
  1. Simplify project management. Logical units of work can be split up among different groups during development process to help simplify project management. 
  2. Conserve memory. If two or more applications use the same DLL, the DLL is loaded into the RAM and this can be shared by all of the applications.
  3. Extend the features of an application. An application can determine the availability of DLL's dynamically load them & extend/limit the functionality of the application.
  4. Flexibility of programming languages. You can choose the language best suited for a particular module. Perhaps use Visual Basic for the UI & C++ for the business logic. 

Writing the application using a DLL

There are two parts to writing this application.
  1. Writing the DLL whose functions we are going to call
  2. Writing a test client for the DLL

Creating the DLL

  1. Fire up Visual C++ & choose the Project as MFC AppWizard(Dll) and type in Project name as MyDll
  2. Let the default selection for DLL type remain, i.e "Regular DLL using Shared MFC DLL"
  3. Click Finish and then Ok to get Visual Studio to generate the necessary files.
  4. Go to the class view, right click on “MyDll classes” and choose “New Class”.
  5. Now choose Class type as "Generic Class" .
  6. Type in the Class name CMyClass, the wizard automatically fills in the rest of the names.
  7. Go to the class view again
  8. Right click on the CMyClass and choose “Add Member Function”
  9. Type in the name of the function type as CString and fill in the function declaration as SayHello (CString strName). Choose Access type of the function as public. Note : CString is a MFC class that makes manipulation of strings very easy.
  10. Now go to file view and type in the following code into CMyClass.cpp as shown below in Code Snippet 2

  11. To be able to call the functions from an external application we have to prefix all function signatures with __declspec(dllexport) . This change is made in the CMyClass.h file as shown in Code Snippet 1

Compile the application and your DLL is ready

// CMyClass.h 
//{-----------     Code Snippet 1 --------------------------
class CMyClass  
{
public:
	__declspec(dllexport)  CString SayHello (CString strName);
	__declspec(dllexport)  CMyClass();
	__declspec(dllexport)  virtual ~CMyClass();

};

//{-----------     Code Snippet 1 --------------------------

// CMyClass.cpp
//{-----------     Code Snippet 2 --------------------------

CString CMyClass::SayHello(CString strName)
{
	//Return the input string with a Hello prefixed 
	 return "Hello " + strName; 
}

//{-----------     Code Snippet 2 --------------------------

Creating the DLL Client

Now we write a 'Client' to test our DLL This is a MFC dialog based application with a edit box and two buttons.
  1. Select New MFC AppWizard(exe) from the project menu and type in the project name TestDLL
  2. Choose Dialog based application and click Finish
  3. You would now be looking at the application in the resource view. Add an edit box to the application by selecting the edit box, next click on the dialog box and drag.
  4. Also create a CString (value) variable associated with it, call this variable m_edit i.e Click on the edit box and press CTRL and W to bring up the class wizard. Choose the member variables tab and choose IDC_EDIT1 and click on “Add Variable”, of type "Value" and type m_edit
  5. Now a file called TestDLLDlg.cpp would have been generated .
  6. Double click the “Ok” button on the dialog, the wizard pops up a box asking a name for the function, choose the default name “OnOk” to go to the TestDLLDlg.cpp file
  7. Modify TestDLLdlg.cpp to look like the Code Snippet 1, the code entered has no effect and the project at this point will not compile. (Basically we are calling a method of a class object, this object has not been defined as yet.)
  8. Goto the file TestDLLDlg.h and include the header file for your class i.e MyClass.h .
  9. In the file TestDLLDlg.h declare an object of your class objMyClass present in the DLL
  10. After steps 8 & 9 the code looks as in Code Snippet 2
  11. We need to modify the project settings to compile the project, Click on "Project->Settings->Link" and in the "Object/Library Modules" enter the complete or relative path to the DLL's library file. i.e. A .lib file is generated in the same folder as your DLL, I have entered "..\MyDll\Debug\MyDll.lib" here.
  12. Compile the application and if it has compiled successfully. Run it. 

    Hey, Why are we getting this stupid box saying "Unable to located DLL" ? 
    Solution: Copy the MyDll.dll to the same folder as the TestDll.exe
    (See my comment http://www.codeproject.com/Articles/2516/Creating-and-consuming-MFC-DLLs-for-Beginners?msg=228387#xx228387xx)
 

Run the application, enter a name in the text box and click the okay button, this will show a message box containing the same text prefixed with a hello.

//TestDLLdlg.cpp
// ----------------- Code Snippet 1 ----------------------------
void CTestDLLDlg::OnOK() 
{
		
	UpdateData(true);
	CString strResult = objMyClass.SayHello(m_edit);
	AfxMessageBox (strResult);
	//CDialog::OnOK();
	
}
// ----------------- Code Snippet 1 ----------------------------
// ----------------- Code Snippet 2 ----------------------------
//TestDLLDlg.h
/////////////////////////////////////////////////////////////////////////////
// CTestDLLDlg dialog


 #include "..\MyDll\MyClass.h" 

class CTestDLLDlg : public CDialog
{
// Construction
public:
	CTestDLLDlg(CWnd* pParent = NULL);	// standard constructor
	 CMyClass objMyClass; 

// Dialog Data

// ----------------- Code Snippet 2 ----------------------------
 

 

After 10 years (of publishing this article) along came Ed to provide some comments which I feel may be useful - http://www.codeproject.com/Articles/2516/Creating-and-consuming-MFC-DLLs-for-Beginners?msg=4338620#xx4338620xx

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Imran Ebrahim
Product Manager
India India
Imran is a software professional with 9 years of development experience and has worked on JAVA, VB6, VC6, C# & some JavaScript.
 
He is interested in Hi-Performance code, OO Methodology, OS API's, Optimizing Windows, Tweaking IE.
 
For the last few years Imran has specialized in developing robust, hi-performance applications & GUI's (Swing) for MNC's.
 
http://techspot121.blogspot.com/

Comments and Discussions

 
GeneralRe: Flexgrid in a dialog from a DLL PinmemberLuisM4-May-04 22:05 
GeneralRe: Flexgrid in a dialog from a DLL PinmemberWenjun Wang5-May-04 4:59 
GeneralRe: Flexgrid in a dialog from a DLL PinmemberLuisM6-May-04 6:27 
GeneralHelp Please PinmemberIliana3-Nov-03 7:36 
GeneralRe: Help Please PinmemberMartín Arbañil19-Dec-03 4:42 
GeneralRunning Error Pinmembermimosa16-Oct-03 11:19 
GeneralDLL guaranteed to work in VB PinmemberChrisNixon29-Sep-03 23:43 
GeneralRe: DLL guaranteed to work in VB PinmemberChrisNixon30-Sep-03 5:17 
Ok, this is the technique, as requested by Harry who emailed me this afternoon. Hope this isn't a let-down! All I can guarantee is that you will be able to call the DLL successfully from other VC and VB apps...
 
First up I should state that this is done in VC++ 6.0 but it is so bare-bones it should work in earlier versions (at least from 4.0 up).
 
First, fire up the AppWizard and choose 'Win32 Dynamic-Link Library'. Enter a name for your DLL project, such as MyDLL, choose a folder and click OK.
 
On the next screen of the Wizard, which asks which type of DLL you would like, choose 'A DLL that exports some symbols', because this provides some template code we can modify (and dump the bits we don't need), and click Finish. For the technically-minded, this option will add exports for one class, one variable and one function. It is the function we are after.
 
Click OK on the final Wizard screen to confirm your choices and our skeletal DLL is built. Now we need to customize it - but it's really, really easy.
 
We'll customize it so that the DLL contains one function named 'AboutBox()', which displays a simple MessageBox when called from your client application. This gives you an easy way to confirm you are accessing the DLL properly.
 
First, click on the FileView tab. Expand all the tree nodes so you can see the source and header files. Double-click 'MyDLL.h' or whatever the main H file in your project is called. Delete the comments at the top (optional), then delete all the lines following the #endif EXCEPT for the last line in the file - this last line is the one and only function created for you by AppWizard, and we will customize it shortly.
 
The file should now look like this:
 
MyDLL.H
----------------------------------------------
 
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
 
MYDLL_API int fnMyDLL(void);
 
----------------------------------------------
 
Now save your work, and double-click 'MyDLL.cpp', or whatever the main CPP of your project is. Underneath the definition of the DLLMain() function are the definitions for the same three items we just altered in the H file, and we need to alter them here too. Remove the definition for the exported variable and the exported class. Leave the exported function. The bottom bit of this file (I won't repeat the MyDLL class definition here) should now look like this:
 
MyDLL.CPP
----------------------------------------------
 
// This is an example of an exported function
MYDLL_API int fnMyDLL(void)
{
return 42;
}
 
----------------------------------------------
 
Almost there. We now have a pretty naff function that does not do a lot. That will change. Go back to the MyDLL.H file and alter the function definition for fnMyDLL() until it looks like this:
 
MyDLL.H
----------------------------------------------
 
MYDLL_API int __stdcall AboutBox(void);
 
----------------------------------------------
 
Go back to MyDLL.cpp and alter the function definition of fnMyDLL() to look like this:
 
MyDLL.CPP
----------------------------------------------
 
MYDLL_API int __stdcall AboutBox(void)
{
return MessageBox(NULL, "My First DLL", "About MyDLL", MB_OK);
}
 
----------------------------------------------
 
Now we need to add a .DEF file (so it works in VB - we don't need this step if we aren't using VB to call the DLL). Click the 'New File' toolbar icon and type the following exactly as it is here (well you can type what you want for the description), and save it as 'MyDLL.DEF' :
 
MyDLL.DEF
----------------------------------------------
 
LIBRARY "MYDLL"
DESCRIPTION "MyDLL Dynamic Link Library"
EXPORTS
AboutBox @1
 
----------------------------------------------
 
You need to add this file to the project, so right-click on the node 'Header Files' in FileView and select 'Add Files to Folder'. In the Insert Files into Project dialog, click on the 'Files of Type' drop-down and choose 'Definition Files (.def)'. Your new MyDLL.def file should now be visible so double-click on it.
 
Now you are ready to compile your DLL. Don't forget to select 'Release' mode! And don't forget to save your work first!
 
To use the DLL from another VC++ program, do the following:
 
Create an MFC (or whatever you prefer) EXE in AppWizard. Make it a Dialog-based application as it's easier to follow the next step.
 
Place a new button on the dialog form. Double-click the new button and you will be prompted to create a member function named 'OnButton1' or similar, depending on whether you changed the resource ID from its default. Click Ok. In the new function body, type the following under the comment line:
 
// TODO: Add your control notification handler code here
AboutBox();
 
Save and close the project because you need to copy some bits over from the MyDLL project before it will compile.
 
So, first copy the actual 'MyDLL.dll' file from the Release sub-folder of your MyDLL project folder, into the Release sub-folder of your new VC++ project. Then, also from the DLL's Release folder, copy the file 'MyDll.lib' but this time to the source code folder of your VC++ project - this is because we want to link to this file in a moment and it's easier not to have to worry about pathnames. Finally, copy the main header file from your DLL project, 'MyDLL.h', over to the source code folder of the new project.
 
Now, re-open the new project. At the top of the CPP file where the new OnButton1() function was added by ClassWizard, add the following line:
 
#include "MyDLL.h"
 
Now, click on the Project menu. Select Settings, then click on the Link tab. In the text box labelled 'Object/Library modules', type MyDLL.lib and click Ok. Remember to make sure you are in Release mode first because we put the DLL in the Release subfolder and the IDE keeps different Link settings for Debug and Release modes.
 
Compile your app (again, make sure you are in Release mode) and run it. Click the button on the dialog and bingo! A small About box will appear.
 
To call your DLL from VB, you will beed to add a 'Declare' statement at the top of your VB project:
 
Public Declare Function AboutBox Lib "MyDLL" () As Long
 
That should do it. I'm no VB coder and I can never remember the syntax but one of my VB colleagues just this morning did just this to access one of my DLLs written in the above manner. I'm sure other VB experts here can help if I have got this line wrong!
 
I hope I haven't missed out any steps. Basically the DLL is easy to get working in VC programs. But for VB, you need to remember two things; the __stdcall function modifier, and the .DEF definition file.
 
Have fun and let me know if you get results, one way or another. I promise to reply to any posts where problems are experienced.
 
PS - to add more functions to your DLL, add their prototypes to the H file and their definitions to the CPP file - and don't forget to add an entry to the .DEF file, use @2, @3 etc as you add more and more.
 
Cheers,
Chris.
 

 

 

 

 

 

 


GeneralRe: DLL guaranteed to work in VB Pinmemberharryr_20031-Oct-03 6:44 
GeneralRe: DLL guaranteed to work in VB PinmemberTommy Svensson8-Jul-04 1:06 
GeneralRe: DLL guaranteed to work in VB PinmemberChrisNixon8-Jul-04 2:23 
GeneralRe: DLL guaranteed to work in VB Pinmembernevedko3-Oct-03 6:00 
GeneralRe: DLL guaranteed to work in VB PinsussNeil Kurzman15-Apr-04 14:07 
GeneralThis article is very useful to me.But I've a question. Pinmemberwhiteclouds17-Sep-03 20:24 
QuestionHow to create a dialog in a dll... Pinmemberombak23-Aug-03 7:15 
AnswerRe: How to create a dialog in a dll... PinmemberRichard.cexo2-Sep-03 16:58 
GeneralRe: How to create a dialog in a dll... Pinmemberasierra5-Sep-03 11:27 
GeneralRe: How to create a dialog in a dll... PinmemberGeorge Clarence17-Feb-04 23:47 
Generalno source code Pinmembereagertolearn16-Jul-03 16:21 
GeneralThank you very much PinmemberMartin_Viet11-Apr-03 4:32 
GeneralError while calling a vc++ dll from vb Pinmemberbijtomy@tatanova.com7-Apr-03 6:38 
GeneralRe: Error while calling a vc++ dll from vb Pinmembercedric moonen11-Apr-03 2:31 
GeneralRe: Error while calling a vc++ dll from vb PinmemberMartin_Viet11-Apr-03 4:56 
Questionhow to export an function through DLL that belongs to a class derived from CWnd generic Pinmemberpranab kumar bharimalla12-Mar-03 20:25 
GeneralCreating and consuming MFC DLLs for Beginners Pinmemberwb120624-Feb-03 4:54 

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

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

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 18 Aug 2012
Article Copyright 2002 by Imran Ebrahim
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid