How to Create a Simple Win32 DLL Using Visual C++ 2005
This tutorial is an update to one I did years back for Visual C++ 6.0. That article has consistently been the most viewed page on icynorth.com by a long shot. I didn’t realize that until a year ago when I started using Google Analytics on the site, but it really surprised me to see. It goes to show that sometimes bringing things back to the basics can be a big hit.
This tutorial will teach you how to use Visual C++ 2005 (Visual Studio 2005 Professional) to create a small Win32 C++ DLL that can be called from C++, Visual Basic, Delphi, C# or any other program capable at calling DLL functions.
This DLL will have one purpose; to generate a unique filename using the Windows API function GetTempFileName. This function is useful if you need to store temporary data in a unique file for the user of your application and want to ensure that the file does not already exist. However, the point of this tutorial is not to generate unique filenames, but rather to show you how easy it is to create simple Windows DLLs using Visual C++.
The key here is “simple”. Windows DLLs are capable of much, much more than outlined here. This tutorial will only cover simple, Win32 DLL creation for those quick-and-dirty projects.
Create the Project
The first step is to start Visual Studio and create our DLL project.
1) Start Visual Studio 2005 and choose File > New > Project from the menu.
This will open the New Project dialog. This is the starting point for creating all kinds of projects. Go to the Project types tree, expand the “Visual C++” node and then select the “Win32″ child node.
2) On the right, in the Templates list, select “Win32 project” and name the project “MakeTempFilenameDLL2005″.
We want to create a Win32 DLL, not a MFC DLL. MFC-based DLLs can also be very useful and offer a lot more functionality, however they require the overhead of the MFC library DLLs just to get started. That is too much overhead for our simple DLL needs.

3) Next you will see the Win32 Application Wizard. The first screen has the heading “Welcome to the Win32 Application Wizard”. Click the Next button.
4) On the Application Settings screen, select “DLL” as the application type. Leave the other fields as they are by default and click Finish.

Your new project will now be ready to work on from the Visual Studio design environment. At this point, your project will compile and your DLL can be created, however it will not do anything because we have not created and exported any functions yet. That is the next step.
Set Project Properties
There are a few project settings that you might want to check/set before continuing. These steps are optional but you should be aware of them because they may apply to your situation. To access the Project Properties dialog, select Project > Properties from the menu.
1) Set the proper Character set.
Open the Configuration Properties tree item and then select the General child item. On the right side, find the Character Set item. By default it will probably have “Use Unicode Character Set” selected. You can leave this as-is if you want your DLL function to be Unicode compliant. Generally you will want to choose Unicode if you will be calling the DLL from a Unicode executable.
If you will be calling your DLL from non-Unicode code, choose “Use Multi-Byte Character Set”.

2) Set the Runtime Library.
On the left side in the properties tree, select Configuration Properties > C/C++ > Code Generation. On the right side, look at the Runtime Library setting. By default it will probably be “Multi-threaded Debug DLL (/MDd)”. This will cause your DLL to link with the DLL (debug) version of the C runtime library. Now, that is OK as long as you are sure that the matching version of the C runtime library DLL will be on the user’s system. However, in general, I like to switch to “Multi-threaded Debug (/MTd)”. This will cause your DLL to statically link to the C runtime library. It will increase the size of the DLL (very minor increase) but will have the benefit of not being dependent on the correct version of the C runtime library DLL. There are other differences between these two options, however such as the way memory is allocated. You should generally try to match your DLLs settings to the setting of the calling program when possible.

3) Repeat.
If you did one or both of the above, they are set for the Debug build configuration of your DLL, but not the Release version (the one you will actually use in production). To set the release version, you will want to select “Release” in the Configuration combo box at the top-left corner of the dialog.
When you are happy with your settings, click OK to save the changes to your project’s properties.
Add the Function
The next step is to actually add the function to the DLL that we want to be able to call from other programs.
1) Open the “MakeTempFilenameDLL2005.cpp” file for editing.
Select the Solution Explorer tab. Then open the Source Files folder. Now double-click on the “MakeTempFilenameDLL2005.cpp” file. You will now be able to edit the file.
2) Add the “RetrieveTempFilename” function.
Next we want to add the actual code for the function. Our function will be called “RetrieveTempFilename”. It will accept two string arguments. The first is “szDirectory” which is the directory that we want to generate the unique filename in. The second argument, “szPrefix” is a string that will be the prefix of the temporary filename. The “GetTempFileName” API function will use the first three characters of this string when generating the unique filename. The function will return the unique filename if successful, or the string “ERROR” if it fails.
Because we want to return a string, we need to make the returned string a global variable. This is necessary because if we declare the string inside of the function it will be destroyed when the function is finished. We need to create a string that will last for the life of the DLL.
Your global string declaration and function should look like this:
TCHAR szReturn[MAX_PATH];__declspec(dllexport) LPCTSTR RetrieveTempFilename(LPCTSTR szDirectory, LPCTSTR szPrefix)
{
TCHAR szBuffer[MAX_PATH];
if(GetTempFileName(szDirectory,szPrefix,0,szBuffer) == 0)
{
// It failed - return the string "ERROR"
lstrcpy(szReturn,TEXT("ERROR"));
} else {
// Success!
lstrcpy(szReturn,szBuffer);
}
return szReturn;
}
Note that the code above is Unicode safe so it will compile properly regardless of which character set you chose. You can copy and paste the code above right into your file below the “DllMain” function.
If you build your project now it will compile successfully but the function will still not be callable from outside programs. That is because the Visual C++ compiler “decorates” the function names so that they would not be recognizable to the calling program. Although there are several ways around this problem, we will use an “Export.def” file.
Add an “Export.def” File
Adding an Export.def file will allow us to tell the compiler the proper names of our DLL functions that should be exposed.
1) Add a new text file to your project called “Export.def”
Choose Project > Add New Item from the menu within Visual Studio and under the Visual C++ category, choose the Code child item. On the right side, select “Module-Definition File (.def)” and type in “Export.def” as the filename. Click OK to create the file.

2) Add the “EXPORTS” sections to the “Export.def” file.
All that we need to do now is to add a section to the “Export.def” file and we will be in business. The file should already contain a “LIBRARY” declaration with our DLL name. We will add an “EXPORTS” section which declares our exported functions.
LIBRARY "MakeTempFilenameDLL2005"
EXPORTS
RetrieveTempFilename
Copy and paste the above lines into the “Export.def” file. Now you can build your project. First of all, make sure you are building the “Release” build by selecting Build > Configuration Manager, choosing “Release” as the Active solution configuration setting and clicking Close. Then just choose Build > Build Solution to build the DLL. It should compile and link with no troubles.
Calling the DLL from C#
To call the DLL from a .NET application written in C#:
1) Add “using System.Runtime.InteropServices;” to the using section at the top of the .cs file.
2) Add a decaration for the function prototype:
[DllImport("MakeTempFilenameDLL2005.dll")]
static extern String RetrieveTempFilename(String strDirectory, String strPrefix);
3) Call the function:
string Filename = RetrieveTempFilename("C:\\Temp", "tmp");
For more information about calling C/C++ Dlls from .NET, see:
Calling Win32 DLLs in C# with P/Invoke
Calling the DLL from Indigo Rose Tools
At this point you have a fully-functional DLL that can be called from Visual Basic, another C++ application or any other program capable of loading can calling DLL functions. Here we will focus on how to call our new function from any of the Indigo Rose development tools that use the Lua scripting language.
The first step will be to put the DLL somewhere that the runtime engine can find it. In the case of Setup Factory or Visual Patch include it as a primer file and call it like this:
local strDLLPath = SessionVar.Expand(
"%TempLaunchFolder%\\MakeTempFilenameDLL.dll");
local strTempFilename = DLL.CallFunction(strDLLPath,"RetrieveTempFilename","\"".._TempFolder.."\",\"tst\"",
DLL_RETURN_TYPE_STRING,DLL_CALL_CDECL);
Dialog.Message("Temp Filename",strTempFilename);
In the case of the other products, simply adjust the strDLLPath variable accordingly.
Conclusion
This tutorial has brought you through the process of creating a simple C++ Win32 DLL using Visual C++ 2005 and calling a DLL function from C# and one of the Indigo Rose development tools. Of course, in the real world your DLL functions will be more complicated and useful, I hope that this tutorial has put you on the right track.
I have prepared a downloadable zip file for you that contains the Visual C++ project and the finished DLL.
Click here to download MakeTempFilenameDLL2005.zip (26 KB)
Brett Kapilik :: Sep.17.2007 :: C++ :: 10 Comments »
10 Responses to “How to Create a Simple Win32 DLL Using Visual C++ 2005”



perfect!! thanks!!
thanks…
The article is fine for creating C++ DLL’s outside the managed environment. I would like to create a DLL which could participate in the managed VM of a parent C# application. How would I create such an assembly?
Great! Thanks a lot!
If you have some time, a tutorial on bilateral communication between application and DLL would be welcome
helped me a lot.
Thanks!
A Very Good article for beginner
Thank you for the great article, I am sure I will use this in future. How can I give you credit for this code?
thanks alot
perfect ,it helped me
but missing calling the dll from c++
Nice tutorial and well presented. I think the function itself is a little complicated esspecially for someone who is unfamiliar with C++
Greetings, Thank you for this example.
However when I follow your directions, the C# application can not load the DLL.
I get the following error:
Unable to load DLL ‘releaseMakeTempFilenameDLL2005.dll’: The specified module could not be found. (Exception from HRESULT: 0×8007007E)
the C# app
—————————————————————————
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
[DllImport(”releaseMakeTempFilenameDLL2005.dll”)]
static extern String RetrieveTempFilename(String strDirectory, String strPrefix);
static void Main(string[] args)
{
string Filename = RetrieveTempFilename(”C:\\Temp”, “tmp”);
Console.WriteLine(Filename);
}
}
}
The DLL is made exactly like in your blog.
I thank you for your time and advice on this.