(Note: I’m using InstallShield 12 for my install development and Visual Studio 2005 for DLL development.)
The goal is to learn to make a simple DLL that I can use in an MSI custom action. Today I started with the basics using a classic book that still has relevance today: Programming Windows 95 by Charles Petzold.
Chapter 19, Dynamic Link Libraries. I got some basic concepts about dynamic linking vs. static linking, what a DLL is, then read though the source code for a simple DLL with a single function.
I open up Visual Studio, start a New Project. The Project Type is Other Languages , Visual C++, Empty Project. Under Solution Explorer, Header Files, I add a new (Code) Header File (.h).
I read the first line out of the book that it wants me to write into a .h file and already I’m lost. Too many keywords that I don’t understand the meaning or use of. The first line is:
#define EXPORT extern “C” __declspec (dllexport)
Huh? So I set about doing some research. The #define statement I can understand. But what about EXPORT? Is that a predefined keyword or what? For some reason I picked the “extern” as the first thing to highlight and then hit F1 in Visual Studio. Eventually I made my way to this section of the MSDN help:
In the MSDN Library, Development Tools and Languages, Visual Studio 2005, Visual Studio, Visual C++, Programming Guide, General Concepts, DLLs, Importing and Exporting, Exporting from a DLL. *whew!*
This whole section was good and explained fairly simply the basic concepts about exporting and what our keywords in this statement were really doing. After looking through this section and also looking through a few sections about using “Windows Installer DLLs” and “standard DLLs” in the InstallShield 12 User Guide (downloadable from the Documentation section off their website), I feel that I have a good basic understanding of what we are trying to do with a DLL. So here’s what I came up with…
In order to setup the DLL so that the functions are exported and made available to external applications, we need to use certain directives that tell the compiler to export them. There is 2 ways to do this – one, use a .def file, two, define export directives and use them in the function declarations. Either method is fine. In C++ programming you are more likely to see the second method, so that’s the method I’m going to use.
So we are going to define some export directives. We *could* put these directives right in the declaration for each function, but to make it simpler, we’ll setup a macro with the directives we want, then just use that (much shorter) macro in front of each function.
So in the header file start off by defining the macro with this code:
#define EXPORT extern “C” __declspec (dllexport)
This defines a macro so that where the term “EXPORT” is used in your function declarations, it will be (essentially) replaced with the whole string that follows it in the above line. So what is all the rest of the string for?
- “extern” tells it to make the function available to external programs
- “C” tells it that we have a C++ function that we want to be accessible to C language modules. This avoids function ‘name decoration’ that would otherwise be used when compiling for C++ language modules.
- “__declspec (dllexport)” allows us to skip having to create and use a .def file for exporting.
By the way I've used "EXPORT" but you could use any term that's valid as a macro name.
Ok, so far so good. I feel I’ve made some progress at learning the fundamental concepts here, so it seems like a good spot to stop. Next time I’ll tackle actually declaring a function!