Build DLL (dynamic linked library) with microsoft visual studio
This article explains how to work with the default microsoft VC 6.0 IDE to compile DLL output from a given c code. It also shows how to use this dll within another given c code.
Let's say you have 3 files, a_main.c, a_dll.c, and a_comm.h. Both .c files use the .h header files. Let's first generate a_dll.dll from a_dll.c. Double click a_dll.c in windows should automatically open a_dll.c within the VC IDE. If this is not the case, you need to associate .c files with VC ide. Next try to compile a_dll.c, at this point, VC will create a workspace template file for you. Now this is the point where you need to make changes to the default workspace/project settings so that instead of linking and producing a EXE file, a DLL file is generated. First set active configuration to win32 release, then open project/settings diaglog. Click on c/c++, this is the compilation settings. You need to put the following defines in the "preprocessor definitions" textfield, _USRDLL and A_DLL_EXPORTS. _USRDLL tells the compiler-preprocessor that this file is intended to be compiled into a DLL file. A_DLL_EXPORTS tells the compiler that this file as DLL exports symbols. A_DLL_EXPORTS is a instantiate of FILENAME_EXPORTS, because we are working with a_dll.c here, we replace FILENAME with A_DLL. If the file was named b_dll.c, we'd have used B_DLL_EXPORTS.
There is another flag _WINDOWS that needs to be added depending on the nature of the DLL. If the DLL has any USR32.DLL imports, working with GUI components, then we must replace the default _CONSOLE flag to _WINDOWS. The VC default project template settings assumes a win32 console application is being compiled. So use either _WINDOWS or _CONSOLE depending on what kind of DLL you are working with. Save your settings change by click on "Ok" button. At this point, a_dll.c should be compiled and seen to produce a_dll.obj without any problem.
Next we must modify the settings that used during VC linking process. The object code is linked with other libraries to produce either a EXE file or a DLL file. The default template project settings will link to a win32 console EXE file. Open the project/settings dialog again in VC and choose the "link" tab. In "Output filename" text field, change a_dll.exe to a_dll.dll. This change tells the linker we desire a dll output from the source code a_dll.c. If you didn't change this and go ahead compiling/linking your code, VC will complain it cannot find "main" or "winmain" function because as a dll source code, a_dll.c contains the dllmain entry instead of main for a console app or winmain for a windows app. In the "Project Options" textarea, get to the end of the option string and add "/dll", this again tells the linker to produce a dll output instead of a exe output.
The last step again depends on what kind of dll it is, console or windows. You don't have to do anything else if it's a console dll because the default setting assumes it's creating a console dll. Otherwise in "Project Options", find "/subsystem:console" and replace it with "/subsystem:windows". Click "Ok" to save the changes and in "Build" menu, you should see the target output has changed from a_dll.exe to a_dll.dll. You should be able to create the desired a_dll.dll now.
Granted, this seems to be a lot of hassle to get VC to generate DLL output from a source code file. This would have been very easy if we could have started from the project wizard and was using a win32 dll template from day 1. But occasionally one cannot always expect a project build configuration is available with a downloaded or copied source code and we have to build a dll file using what we have at hand. The trick I explained above demonstrates the step by step changes to the default project settings to genreate a dll file.
Now onto the next step building a.exe using the newly generated a_dll.dll. Again load a.c into VC and let VC generate a default project template file to work with. If you would try to build a.exe now, VC would complain missing functions in a_dll.c during link. To fix this, open Project/Settings, and go to link tab. In Object/library modules text, go to the end of the list and type in PATH_TO_A_DLL_LIB\a_dll.lib. Here PATH_TO_A_DLL_LIB is the path to a_dll.lib file. For example, if you have organized your files in c:\myfiles. PATH_TO_A_DLL_LIB would be Release or Debug depending on what build configuration was used when a_dll.dll was built. This is the only change you need to make to link a.obj with a_dll.lib to generate the final product: a.exe.
It's interesting to note that the compiler actually links a.obj with a_dll.lib instead of a_dll.dll to build a.exe. a_dll.dll is only used when a.exe is running in the system, as it's name implied dynamic link library.
Let's say you have 3 files, a_main.c, a_dll.c, and a_comm.h. Both .c files use the .h header files. Let's first generate a_dll.dll from a_dll.c. Double click a_dll.c in windows should automatically open a_dll.c within the VC IDE. If this is not the case, you need to associate .c files with VC ide. Next try to compile a_dll.c, at this point, VC will create a workspace template file for you. Now this is the point where you need to make changes to the default workspace/project settings so that instead of linking and producing a EXE file, a DLL file is generated. First set active configuration to win32 release, then open project/settings diaglog. Click on c/c++, this is the compilation settings. You need to put the following defines in the "preprocessor definitions" textfield, _USRDLL and A_DLL_EXPORTS. _USRDLL tells the compiler-preprocessor that this file is intended to be compiled into a DLL file. A_DLL_EXPORTS tells the compiler that this file as DLL exports symbols. A_DLL_EXPORTS is a instantiate of FILENAME_EXPORTS, because we are working with a_dll.c here, we replace FILENAME with A_DLL. If the file was named b_dll.c, we'd have used B_DLL_EXPORTS.
There is another flag _WINDOWS that needs to be added depending on the nature of the DLL. If the DLL has any USR32.DLL imports, working with GUI components, then we must replace the default _CONSOLE flag to _WINDOWS. The VC default project template settings assumes a win32 console application is being compiled. So use either _WINDOWS or _CONSOLE depending on what kind of DLL you are working with. Save your settings change by click on "Ok" button. At this point, a_dll.c should be compiled and seen to produce a_dll.obj without any problem.
Next we must modify the settings that used during VC linking process. The object code is linked with other libraries to produce either a EXE file or a DLL file. The default template project settings will link to a win32 console EXE file. Open the project/settings dialog again in VC and choose the "link" tab. In "Output filename" text field, change a_dll.exe to a_dll.dll. This change tells the linker we desire a dll output from the source code a_dll.c. If you didn't change this and go ahead compiling/linking your code, VC will complain it cannot find "main" or "winmain" function because as a dll source code, a_dll.c contains the dllmain entry instead of main for a console app or winmain for a windows app. In the "Project Options" textarea, get to the end of the option string and add "/dll", this again tells the linker to produce a dll output instead of a exe output.
The last step again depends on what kind of dll it is, console or windows. You don't have to do anything else if it's a console dll because the default setting assumes it's creating a console dll. Otherwise in "Project Options", find "/subsystem:console" and replace it with "/subsystem:windows". Click "Ok" to save the changes and in "Build" menu, you should see the target output has changed from a_dll.exe to a_dll.dll. You should be able to create the desired a_dll.dll now.
Granted, this seems to be a lot of hassle to get VC to generate DLL output from a source code file. This would have been very easy if we could have started from the project wizard and was using a win32 dll template from day 1. But occasionally one cannot always expect a project build configuration is available with a downloaded or copied source code and we have to build a dll file using what we have at hand. The trick I explained above demonstrates the step by step changes to the default project settings to genreate a dll file.
Now onto the next step building a.exe using the newly generated a_dll.dll. Again load a.c into VC and let VC generate a default project template file to work with. If you would try to build a.exe now, VC would complain missing functions in a_dll.c during link. To fix this, open Project/Settings, and go to link tab. In Object/library modules text, go to the end of the list and type in PATH_TO_A_DLL_LIB\a_dll.lib. Here PATH_TO_A_DLL_LIB is the path to a_dll.lib file. For example, if you have organized your files in c:\myfiles. PATH_TO_A_DLL_LIB would be Release or Debug depending on what build configuration was used when a_dll.dll was built. This is the only change you need to make to link a.obj with a_dll.lib to generate the final product: a.exe.
It's interesting to note that the compiler actually links a.obj with a_dll.lib instead of a_dll.dll to build a.exe. a_dll.dll is only used when a.exe is running in the system, as it's name implied dynamic link library.
<< Home