Tuesday, August 13, 2013

Create C Program with Dynamic Link Library (DLL) using Command Line (Implicit Link) in Windows

The following procedure is to create a C program with a dynamic link library using Developer Command Prompt for VS2012.

Brief Introduction to Dynamic Link Library (DLL)
The important difference between DLL and static library is that the code of external function is stored in the DLL file, whereas when linking with static library, the code of the external functions is copied to the execution file of the application program. With static library, you just need an execution file whereas with DLL you need both the execution file and the DLL file for the program to work.

Implicit or Explicit Link
When creating DLL, we have the choice of implicit linking or explicit linking. Since implicit linking is easier and common, this article will focus on implicit linking. For additional information please refer to the following:

Linking Implicitly
Linking Explicitly
Determining Which Linking Method to Use

Examples:
The following example is a normal C program with functions. 

#include <stdio.h>
#define PI 3.1415

double PowerOf2 (double UserNumber);
double PowerOf3 (double UserNumber);
double CircleArea (double UserRadius);
double CircleCircum (double UserRadius);

int main ( )
{

 double p2 = 10.0;
 double p3 = 5.0;
 double radius = 4.0;

 printf ("The number %.2f to the power of 2 is %.2f. \n", p2, PowerOf2(p2));

 printf ("The number %.2f to the power of 3 is %.2f. \n", p3, PowerOf3(p3));

 printf ("A circle with a radius of %.2f, the area is %.2f. \n", radius, CircleArea(radius));

 printf ("A circle with a radius of %.2f, the circumference is %.2f. \n", radius, CircleCircum(radius));

 return 0;

}

double PowerOf2 (double UserNumber)
{
 return UserNumber * UserNumber;
}


double PowerOf3 (double UserNumber)
{
 return UserNumber * UserNumber * UserNumber;
}

double CircleArea (double UserRadius)
{
 return UserRadius * UserRadius * PI;
}
 
double CircleCircum (double UserRadius)
{
 return 2 * UserRadius * PI;
}

We will use the above example to create a dynamic link library and an application program that use this library. We will place the DLL in a shared public folder and place the application in the personal document folder.


To create Dynamic Link Library
To create a dynamic link library, it consist of 2 files MyCMathDll.h and MyCMathDll.c

Step 1: Create a header file for DLL
Open a notepad  and create the headers of the DLL as follows. Named the file as MyCMathDll.h

Important: Please make sure that you save the file in program.c instead of program.c.txt. Notepad save everything in .txt extension by default. To avoid this problem, under the file explorer select Organize >> Folder and search option, select the view tab and clear the check on "Hide  extensions for known file types".

Add the following to the headers:

#ifdef MYCMATHDLL_EXPORTS
#define MYCMATHDLL_API __declspec(dllexport) 
#else
#define MYCMATHDLL_API __declspec(dllimport) 
#endif

#define PI 3.1415

MYCMATHDLL_API double PowerOf2 (double UserNumber);
MYCMATHDLL_API double PowerOf3 (double UserNumber);
MYCMATHDLL_API double CircleArea (double UserRadius);
MYCMATHDLL_API double CircleCircum (double UserRadius);

The dllexport and dllimport attributes are extensions to the C and C++. You can use them to export and import functions to or from a DLL. When the MYCMATHDLL_EXPORTS symbol is defined, the MYCMATHDLL_API symbol will set the __declspec(dllexport) modifier in the member function declarations. This enables the function to be exported by the DLL so that it can be used by other applications. When MYCMATHDLL_EXPORTS is undefined, MYCMATHDLL_API defines the __declspec(dllimport) modifier in the member function declarations. This enables the compiler to optimize the importing of the function from the DLL for use in other applications. Using command line, you need to use /D option to define MYCMATHDLL_EXPORTS during compilation.

You can also define the header file this way.

#define PI 3.1415

__declspec(dllexport) double PowerOf2 (double UserNumber);
__declspec(dllexport) PowerOf3 (double UserNumber);
__declspec(dllexport) CircleArea (double UserRadius);
__declspec(dllexport) double CircleCircum (double UserRadius);

For further information on dllexport and dllimport please refer to this article.


Step 2: Create the source code for the functions
Open a notepad  and create the source code of the DLL as follows. Named the file as MyCMathDll.c

#include "MyCMathDll.h"

double PowerOf2 (double UserNumber)
{
 return UserNumber * UserNumber;
}


double PowerOf3 (double UserNumber)
{
 return UserNumber * UserNumber * UserNumber;
}

double CircleArea (double UserRadius)
{
 return UserRadius * UserRadius * PI;
}
 
double CircleCircum (double UserRadius)
{
 return 2 * UserRadius * PI;
}


Step 3: Compile and create the DLL
Open the Developer Command Prompt for VS2012. Use the  option /LD to generate DLL file. If you have included the pre-processor MYCMATHDLL_EXPORTS, use /D option. The command is as follows: 

cl /DMYCMATHDLL_EXPORTS MyCMathDll.c /LD 


Debug any error for compilation error. The compiler should generate an object file, an export file, a library (lib) file named MyCMathDll.lib and a DLL file named MyCMathDll.dll.

If you use the following for headers:

__declspec(dllexport) double PowerOf2 (double UserNumber);

Then the compilation command will be 

cl MyCMathDll.c /LD 





Create a C Application Program Using DLL

Step 1: Create an application program
Open a notepad and create the application program making use of the functions in the DLL as listed below. Named the file as MyApp3.c. Save the file in your personal folder.

Please note that you must know the location of the header file. You need to indicate the header file name and extension if the header file is in the same folder as this program. Otherwise you need to specify the full path in the program or alternatively you could specify the include path during compilation time. The latter method is much preferred because you don't need to change the program when the header file relocate.

#include <stdio.h>
#include "MyCMathDll.h"

int main ( )
{

   double p2 = 10.0;
   double p3 = 5.0;
   double radius = 4.0;

   printf ("The number %.2f to the power of 2 is %.2f. \n", p2, PowerOf2(p2));

   printf ("The number %.2f to the power of 3 is %.2f. \n", p3, PowerOf3(p3));

   printf ("A circle with a radius of %.2f, the area is %.2f. \n", radius, CircleArea(radius));

   printf ("A circle with a radius of %.2f, the circumference is %.2f. \n", radius, CircleCircum(radius));

 return 0;

}

Step 2: Compile the program
Before compilation, you must know the full path of the lib file MyCMathDll.lib. If you did not specify the full path of your header file MyCMathDll.h you need to use /I option to indicate the search path for the headers file. 

cl MyApp3.c /I C:\Users\Public\Documents\MyCMathDll\ C:\Users\Public\Documents\MyCMathDll\MyCMathDll.lib 


If your program include the full path of the header file as shown below:

#include <stdio.h>
#include "C:\Users\Public\Documents\MyCMathDll\MyCMathDll.h"

// The rest of the program....

}

Then, the command for compilation is simpler:

cl MyApp3.c C:\Users\Public\Documents\MyCMathDll\MyCMathDll.lib 


Step 3: Run the program
Test the program using normal command prompt as shown



If I run my program from my personal folder, I encounter this error because the system could not locate the DLL file.

Please note that for the successful execution of the program. MyApp3.exe and MyCMathDll.dll should be in the same folder. Alternatively, the MyCMathDll.dll should be located where the Windows system could find. The search path the DLL files for Windows are as follows:
  1. The directory where the exe file is located.
  2. The Windows system directory. 
  3. The Windows directory. 
  4. The directories listed in the PATH environment variable.
To rectify the problem above I need to copy MyCMathDll.dll to the folder containing the exe file.

It is not advisable to place the DLL file in system folder or windows folder. For larger software firms that produces many software products, it is the common practice to place the commonly shared dll files under Program Files >> Common Files

This completes the procedure for creating a DLL in C using command line. Please note that the procedure for creating similar DLL using Visual Studio IDE is different





*****


No comments:

Post a Comment

Note: Only a member of this blog may post a comment.