Determining Which Exporting Method to Use
You can export functions in either of two ways—a .def file or the __declspec(dllexport) keyword. To help you decide which way is better for your DLL, consider these questions:
Do you plan to export more functions later?
Is your DLL used only by applications that you can rebuild, or is it used by applications that you cannot rebuild—for example, applications that are created by third parties?
Exporting functions in a .def file gives you control over the export ordinals. When you add an exported function to your DLL, you can assign it a higher ordinal value than any other exported function. When you do this, applications that use implicit linking do not have to relink with the import library that contains the new function. This is very convenient if you are designing a DLL for use by many applications because you can add new functionality and also ensure that it continues to work correctly with the applications that already rely on it. For example, the MFC DLLs are built by using .def files.
Another advantage to using a .def file is that you can use the NONAME attribute to export a function. This puts only the ordinal in the exports table in the DLL. For DLLs that have a large number of exported functions, using the NONAME attribute can reduce the size of the DLL file. For information about how to write a module definition statement, see Rules for Module-Definition Statements. For information about ordinal export, see Exporting Functions from a DLL by Ordinal Rather Than by Name.
A disadvantage of using a .def file is that if you are exporting functions in a C++ file, you either have to put the decorated names in the .def file or define the exported functions by using extern "C" to avoid the name decoration that's done by the Visual C++ compiler.
If you put the decorated names in the .def file, you can obtain them by using the DUMPBIN tool or by using the linker /MAP option. The decorated names that are produced by the compiler are compiler-specific; therefore, if you put the decorated names that are produced by the compiler into a .def file, the applications that link to the DLL must also be built by using the same version of the compiler so that the decorated names in the calling application match the exported names in the .def file of the DLL.
Using __declspec(dllexport) is convenient because you do not have to worry about maintaining a .def file and obtaining the decorated names of the exported functions. However, the usefulness of this way of exporting is limited by the number of linked applications that you are willing to rebuild. If you rebuild the DLL with new exports, you also have to rebuild the applications because the decorated names for exported C++ functions might change if you use a different version of the compiler to rebuild it.