Click here to Skip to main content
Click here to Skip to main content

Creating and consuming MFC DLLs for Beginners

By , 18 Aug 2012
 

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)

About the Author

Imran Ebrahim
Product Manager
India India
Member
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/

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralGood "how" starting point, needs more "why"memberVaclav_Sal30 Mar '13 - 6:59 
Good “how to” article, however it really does not serve as good teaching / learning tool especially for a beginner.
Instead of “type this...than type that “ it should explain the necessary flow of information required to use DLL. And it does that very poorly, thus you get replies “how to do this in such and such IDE”.
The question was posted because the article did not explain the “why this way ” part of building DLL application using DLL.
GeneralRe: Good "how" starting point, needs more "why"memberImran Ebrahim30 Mar '13 - 7:34 
" ... necessary flow of information required to use DLL ...." ????? - If you can improve your comment writing skills, it would be great.
 
However the title of your comment makes sense, yes I agree with you. However the original intent of the article was not meant to be a philosophical discussion as to why things are done the way they are, rather the focus was to provide step by step instructions on getting a small 'hello world' program up and running.
SuggestionWrong information [modified]memberEdd_14 Aug '12 - 11:58 
In your SayHello function:
return "Hello " + strName; 
 
This is completely wrong.
"Hello" (an LPCSTR) is on the left side of + and CString is on the right, which means + operator acts as LPCSTR+, not CString+.
LPCSTR does not have overloaded + operator to append strings.
Keyword return will create a temporary CString object, but + operator still acts as LPCSTR+ not CString+.
This shouldn't even compile.
 
There are many alternatives:
return CString( "Hello " ) + strName;
or
strName.Insert( 0, "Hello " );
return strName;
or
CString retval;
retval = "Hello ";
retval += "strName;
return retval;
 
Your DLL fuctions accept CString arguments.
This is not a good idea.
While your particular usage looks ok, there are issues with passing/returning CString objects between EXEs and DLLs because of CString reference counting.
I recommend using LPCTSTR for arguments and return types for exported DLL functions:
 
LPCTSTR SayHello( LPCTSTR text )
{
  CString tmp;
  tmp = _T("Hello ");
  tmp += text;
  return (LPCTSTR)tmp;
}


modified 14 Aug '12 - 18:11.

GeneralRe: Wrong informationmemberImran Ebrahim17 Aug '12 - 21:09 
Thank you for your feedback Ed, will include a link to your comment in my article.
QuestionWhat happens if shared MFC DLL is missing? Which are files linking to it?memberdjninjarocks26 Jul '12 - 23:10 
I am building a MFC based DLL file and in the creation to reduce my file size, I chose "Regular DLL using shared MFC DLL" in the MFC DLL creation wizard. I'm sure I have supporting files in my PC for the shared DLL. If the system in to which I'm going to install my application lacks shared MFC DLL, I want to divert my customer to a download page or would like to include all the supporting files along with my application installation package.
 
But I don't, which all are the shared mfc dll files, name of dll's or the downloadable package that contains these dll's (for example something like Microsoft .NET Framework)
 
Please help!
AnswerRe: What happens if shared MFC DLL is missing? Which are files linking to it?memberruiwng21 Aug '12 - 2:21 
You can use the tool Dependency Walker which can enumerate all the modules that an executable file or a dll depends on.It also lists all the import and export functions of the module.Here is a download link:http://www.dependencywalker.com/[^]
QuestionPlease Build Step-BY-Step project to use open source DLL in VC++ 2010 MFC ApplicationmemberSumit Makhe8 Mar '12 - 21:15 
I spent Days looking for a good tutorial about using 7zip.DLL to implement compression in VC++ 2010 MFC application. I'm still at step one i.e. How to use Open source DLLs in VC++. This Module is one of the parts of my project. Please Help me or point me to the right direction. I'm Running out of time...
GeneralMy vote of 1membergoldenrose91 Mar '11 - 3:36 
.
QuestionNice, but how do you "debug" this DLL?memberrbid29 Jul '09 - 22:14 
Do you have any hint?
 
  1. I have a MFC Regular DLL with the code I want to share from one MFC Dialog to be used by a non MFC application.
  2. In the same project space I have created a non MFC Client application that will use the public interface of this DLL for testing the DLL (Just a plain console application).
  3. To make the testing more close to the real world, I have copied the *.dll/*.lib to the TestConsole directory
 
How do you run the debugger into the code of the DLL?
 
-- Ricky Marek (AKA: rbid)
-- "Things are only impossible until they are not" --- Jean-Luc Picard
 
My articles
 

AnswerRe: Nice, but how do you "debug" this DLL?memberKarstenK19 Aug '09 - 21:23 
you must build the dll in debug mode and than you should step into it.
 
Press F1 for help or google it.
Greetings from Germany

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 18 Aug 2012
Article Copyright 2002 by Imran Ebrahim
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid