Sie sind auf Seite 1von 19

What is DLL and what are their usages and advantages?

DLL is the abbreviated form of Dynamic Link library. Dynamic link library are the application
extension. When we have some common code between many applications we use a common
extension executable called DLL. In Windows system DLLs are very popular. However in Linux
and Unix like system it is also present and the file extensions are .so or .ko etc. In system side
also DLLs are used like the drivers are the DLL or extensions for the Operating Systems itself.

In the past when MS DOS was used as OS, executables were the only binary running in the
memory and any common code like C library were linked as static code. The main disadvantages
were:

1. Additional executable code adds executable storage size as well as runtime memory
requirement,
2. Executable uses C library code which is available at the time of build or compilation.
There is no way to use latest C library during execution. It needs to be rebuild/recompile
with latest C runtime every time a new C library version released,
3. In multitasking system where more than one task is running, there is no concept of using
one instance of common executable while using static linking. It does not ensure only one
version of C library is running in the system. Also it overloads memory requirement of
each running task.

Dynamic linking resolves all the shortcomings of static linking. Following are the advantages:

1. No additional requirement of memory at runtime or disk storage as a common binary file


will be there,
2. All the application or clients will be using one single version of the common code
provided by the DLL,
3. Operating system loads only one instance of the DLL when the first application/client
loads it then for the every subsequent application it shares the memory pages of the DLL
with their process address space. Thus there is no unnecessary memory overload in the
system.

What are the sections in a DLL executable/binary?

Every DLLs are regular PE executable in windows or ELF binary in Linux. Thus it has sections
like CODE/.TEXT, .DATA,.BSS etc.

• CODE/.TEXT - section contains executable hex code.


• .DATA - section contains global/static data values.
• .BSS - section is for un-initialized global/static values

There are also two major section of a DLL executable. They are import section and export
section.
• Import section(.idata): Defines the list of symbols/functions it imports from an external
executables/modules.
• Export Section(.edata): Defines the list of symbols/functions that DLL itself exposes to
external world to use.

Any executable in windows follows PE/COFF portable executable and common object format.
These formats defines how code area, data area and other areas will be arranged.
There are several tools available to see the various sections of a PE executable. Some of the well
known tools are PE Viewer, PE Explorer etc.

Where should we store DLLs ?

Current application path is the default path of any dependent DLL(s). Thus DLL should reside in
the same directory as the application executable.
However there is some system specific locations for storing operating system shared DLLs.

Windows:

• %systemroot%
• %systemroot%\system
• %systemroot%\system32
• %systemroot%\system32\drivers

Linux:

• /lib
• /lib/modules
• /usr/local/lib

The last location where we can place our DLLs are the directories in the system and or user
PATH environment variable.

Explain the working mechanism of a DLL?

To understand the mechanism of a DLL lets take an example of an application App1 and C
library as DLL. Application App1 calls as C function fopen() at run time.

During compilation and linking: App1.c

#include<stdio.h>

inr main(int argc, char *argv[])


{
FILE *fp = NULL;
fp = fopen(<file>, mode);
fclose(fp);
}
Here App1 uses prototype of fopen() from stdio.h. This is an exported function of C library.
Also App1 has been linked with C library import file. After linking the binary of App1 has
CODE/.TEXT, .DATA, .BSS and one extra section .idata. This .idata section contains the
information of imported function and corresponding name of DLL.
Here the information is like
Name of the DLL: msvcrt.dll
Import function list: fopen(), fclose(), ..

Now lets us look into the sections of msvcrt.dll/C library executable. It has as normal
CODE/.TEXT, .DATA, .BSS and one extra section .edata.

This export section contains a list of functions it exposes to the external world.
Export function list for msvcrt.dll: fopen(), fclose(), ..

Now suppose user executes App1. A chain of events occurs inside system.

• Operating system shell and loader reads and verifies this executable.
• Loader loads the code and data segments in memory.
• Creates BSS section and prepare stack.
• Before going to execution it looks for the imported DLLs from .idata section.
• It recursively loads all the dependent DLLs. If the specified DLL is already loaded then it
only shares the pages to this task. If corresponding DLL not found or found corrupted
then it quits.
• Now dynamic linker links all the imported symbols of App1 to all the exported symbols
of the DLL. This is done by putting appropriate virtual address of exported function in
imported function pointer list entries in .idata section of App1.
• In this way it resolves all the symbols in the import table. If wrong version of dll is
loaded or some of the imported function are not available then it quits.
• Finally if all goes well. It starts execution.
• When App1 calls an imported function it actually calls the corresponding entry in import
table. As the import table entry contains the proper virtual address of the function thus it
jums to the function inside DLL.

The above steps are true for implicit linking. For explicit linking we do not use .idata section
thus loader does not load the DLL at startup. It loads at runtime. For this user has to implement
this import table mechanism all by itself by the use of function pointer/function pointer list. We
have explained this explicit linking mechanism in detail in later section named [What is implicit
and explicit linking in dynamic loading?].

Who loads and links the DLLs?

Windows and Linux both has PE/ELF binary loader to load executable and modules.
A loader in OS loads executable/extension when creating a process or when an application
explicitly calls LoadLibrary() or LoadModule() to load a particular executable.
A loader loads any executable in the following steps.
1. Find the executable in current/system/in path variable
2. If not found through error
3. If found check for signature of executable (say check signature of ELF ) for validity
4. Load the code and data section in application/system address space.
5. Links the imported symbols of the application with the exported symbols of the DLL.

What is dependency chain when using DLL?


When in an application we use functions which has been imported from a DLL(say DLL1) then
the application is dependent on that DLL or DLL1. Thus application has a child dependency on
DLL1. Now suppose for some purpose DLL1 imports some functions from another DLL say
DLL2. Then this DLL1 has a dependency on DLL2. Thus the total hierarchy of dependency
chain is like

+ Application
+ DLL1
+ DLL2

Example:
Suppose our application Application1 uses a standard C library call fopen() which has been
imported from C runtime (msvcrt.dll). Again this library DLL is dependent on Win32 subsystem
for fopen(). It actually calls Win32 API CreateFile() to kernel32.dll. Again this CreateFile()
Win32 API actually calls NtCreateFile() in Ntdll.dll and finally Ntdll.dll resolves this call by
invoking a software interrupt to operating system kernel.
Thus dependency chain looks like:

+ Application 1 (fopen() call)


+ msvcrt.dll (CreateFile() call)
+ kernel32.dll (NtCreateFile() call)
+ Ntdll.dll (software interrupt)
- NT OS Kernel

Microsoft Visual Studio 6.0 has a nice tool to explore the dependency of DLLs and executables
named Dependency Walker. Location \Program Files\Microsoft Visual
Studio\Common\Tools\DEPENDS.EXE

How many types of linking are there?

There are two main categories of linking - Static Linking and Dynamic Linking.

Static Linking - In this type of linking, linker links the actual code of the library direct into the
code section of the executable.
Example: Linking C and Graphics library in Turbo C++ for MS DOS.
Linking an application with a archive contains .obj files.

Dynamic Linking - Dynamic linking does not link the actual code of the external functions.
Instead it prepares a list of imported functions in .idata section and a stub code which actually
jumps to the external function by address.

Again Dynamic Linking can be divided into two category


Implicit Dynamic Linking and Explicit Dynamic Linking.

Implicit Dynamic Linking - Links the code with the import library using .idata section
mechanism. At the time of application launching all the dependent DLLs should be loaded to
start execution. Also when application ends execution all the dependent DLLs are getting
unloaded.

Explicit Dynamic Linking - This linking does not require any .IMPORT section to list the
function entries. It is done at runtime. User calls the Win32 API LoadLibrary() to load a
particular DLL from a specific path on the demand basis at runtime. Thus there is no requirement
for the DLL to be loaded at the startup time. Also DLL can be unloaded after the use with
FreeLibrary() call.

What is the entry point function of a DLL?

DllMain() is the entry point of any Win32 DLL. The function prototype and description are as
follows.
Prototype:

BOOL APIENTRY DllMain(


HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved);

Return value: 0 for success, non zero for error.


APIENTRY - tells the compiler that it is an external/exported function.
hModule - This is the instance handle of the Loaded DLL.
ul_reason_for_call - reason for calling this DllMain() from Win32 subsystem
lpReserved - reserved variable.

ul_reason_for_call can have the following values

1. DLL_PROCESS_ATTACH (value 1) - when a process attaches to the DLL


2. DLL_THREAD_ATTACH (value 2) - when a thread attaches to the DLL
3. DLL_THREAD_DETACH (value 3) - when a thread detaches from the DLL
4. DLL_PROCESS_DETACH (value 0) - when a process detaches from the DLL
What is implicit and explicit linking in dynamic loading?

Implicit Dynamic Linking or loading: When application or client uses its import table to link the
external symbol/functions, it is called implicit linking. In implicit linking application use
prototype header and import library to link an external symbol.

Example: Suppose we have a third party math library and add() is a function/interface we are
using in our application.

Then the following steps are needed

1. include the math.h where add() prototype is there as a import function for compilation,
2. include math.lib for linking.
3. place math.dll DLL at the path of our application.

Explicit Dynamic Linking/Loading: When application does not link the external symbol by
import library rather it loads the DLL at runtime. It does the same mechanism as operating
system does during loading of the implicit linked DLL calls.

This is done by using Win32 APIs like:

• LoadLibrary() - loads and links a input library form the DLL path, or current path,
• GetProcAddress() - finds the symbol/function address by its name for a loaded DLL
• FreeLibrary() - unloads the loaded DLL instance

How functions are imported and exported in a module?

Importing functions - Importing a function from other module is done by placing the function
entry in function list of .IDATA section. MS VC++ compiler has specific keyword
__declspec(dllimport) to import a function or variable from an external module.

Syntax:
Functions: __declspec(dllimport) <function prototype>;
Variables: __declspec(dllimport) <type definition>;

Example:

__declspec(dllimport) int extrn_var;


__declspec(dllimport) int Function1(int a);
Exporting functions - Exporting a function from a module is done by placing the function entry
in function list of .EDATA section. MS VC++ compiler has specific keyword
__declspec(dllexport) to export a function or variable from a module.

Syntax:
Functions: __declspec(dllexport) <function prototype>;
Variables: __declspec(dllexport) <type definition>;

Example:
__declspec(dllexport) int extrn_var;
__declspec(dllexport) int Function1(int a);

How can I export a function from a module?

Exporting a function from a module is done by placing the function entry in function list of
.EDATA section. MS VC++ compiler has specific keyword __declspec(dllexport) to export a
function or variable from a module.

Syntax:
Functions: __declspec(dllexport) <function prototype>;
Variables: __declspec(dllexport) <type definition>;

Example:
__declspec(dllexport) int extrn_var;
__declspec(dllexport) int Function1(int a);

The second method of exporting a method from a module is done by placing function name in
a .def file in EXPORTS section. We have a later section export a function without
__declspec(dllexport) keyword to discuss this in details.

What is the utility of the keyword: __declspec(dllimport),


__declspec(dllexport)?

To answer this question we have to revisit the meaning of these keywords. MS VC++ compiler
treats any variable/function with __declspec(dllimport) as imported from other modules. For
__declspec(dllexport) the mechanism is reversed. With __declspec(dllexport) keyword compiler
treats this symbol to be exported from the module and thus external modules can import this
symbol.

Example:
Suppose I am writing a math library which has a function add(). Now I want my add() function
to export from my module or rather expose this to outside world.
In my math.c I shall write like this

/*math.c*/
int __declspec(dllexport) add(int a, int b)
{
return (a + b);
}
Now when I shall build, I shall get the binary math.dll as well as math.lib.
After getting this files I shall create by math package with three files and they are

1. Binary i.e. math.dll


2. Import Library i.e. math.lib
3. math interface header i.e. math.h

In my math.h I shall declare my add() interface as


/*math.h*/
int __declspec(dllimport) add(int a, int b);
Any application which will use my math package will include my header at compile time. Also
math.lib is needed at linking time. Finally when running the application math.dll will be needed.

How can I export a function without __declspec(dllexport) keyword?

In general __declspec(dllexport) keyword is the common way to export a function from a


module. Export definition file or .def file is another way to include and list the names of the
exported functions/symbols of a module. It works with the MS VC++ linker. It tells the linker to
export the names.

Here are the syntax of a .def file:

LIBRARY <Library/DLL Name>


EXPORTS
<Function Name1> @1 PRIVATE
<Function Name2> @2 PRIVATE
Please note comments are given after ";" and @ defines the ordinal number or the index of the
function in the export table.

Example:
; MyDll.def : Declares the module parameters.
LIBRARY "MyDll.DLL"
EXPORTS
DllCanUnloadNow @1 PRIVATE
DllGetClassObject @2 PRIVATE
DllRegisterServer @3 PRIVATE
DllUnregisterServer @4 PRIVATE

Why the keyword extern "C" is used for codes when used with a C++
compiler?
C functions or symbols are links as the name with under score prefixed with. If the function
name is main() the linking symbol name will be _main(). Also if a variable name is int count;
The linking symbol name will be _count.

For C++ compiler this is not true. C++ has function overloading mechanism. If C++ uses only
under score before function name to link its symbol the purpose of overloading will not be
resolved.

Take an example
Suppose in C++ we have add() function overloaded as
int add(int a, int b) - adds a and b, two arguments
int add(int a, int b, int c) - adds a, b and c, three arguments

Now if C++ uses _add() as symbol name then the two function body can never be linked.
To overcome this limitation of C, C++ linker uses name mangling. It modifies the name of the
function like as <function index><function name>@<argument size>

Example will be
int add(int a, int b) links to _1add@8
[function index 1, function name = add, argument size= sizeof(int)*2 = 8]

int add(int a, int b, int c) links to _2add@12


[function index 2, function name = add, argument size= sizeof(int)*3 = 12]

Extern "C" key word does the reverse it maintains the linking style of C while linking with C++
compiler.
Thus even if we compile a function of a C++ file with C++ compiler, it links as C convention
thus overloading of this function is not possible.

Example extern "C" int add(int a, int b);

Thus most of the C header files when compiles in C++ code/compiler are enclosed as

#ifdef __cplusplus
extern "C" {
#endif
/*List of C function */
#ifdef __cplusplus
}
#endif
#endif

What is name mangling in C++ function?

C compiler links a function or symbol with appending under score before it. Function name
main() links to symbol name _main(). Also if a variable name is int count; The linking symbol
name will be _count.
For C++ compiler this is not true. C++ has function overloading mechanism. If C++ uses only
under score before function name to link its symbol the purpose of overloading will not be
resolved.

Take an example
Suppose in C++ we have add() function overloaded as
int add(int a, int b) - adds a and b, two arguments
int add(int a, int b, int c) - adds a, b and c, three arguments

Now if C++ uses _add() as symbol name then the two function body can never be linked.
To overcome this limitation of C, C++ linker uses named mangling.

Name mangling is the mechanism of C++ compiler to link functions and variables of same
names to resolve them to some unique symbol names by altering the names with some extra
information line index, argument size etc.
Function name mangling is done as <function index><function name>@<argument size>
Variable name mangling is done as ?<variable name>@@<UNIQUE ID>

Example will be
int add(int a, int b) links to

_1add@8 [function index 1, function name = add, argument size= sizeof(int)*2 = 8]

int add(int a, int b, int c) links to


_2add@12 [function index 2, function name = add, argument size= sizeof(int)*3 = 12]

int extrn_var links to


?extrn_var@@3HA [variable name = extrn_var, UNIQUE ID = 3HA ]

How a whole class can be exported?

With VC++ a class can be exported with the following syntax.


Syntax: class __declspec(dllexport) <class name>;
Example:

class __declspec(dllexport) CExportClass1


{
void Function1(void){}
};
Mechanism: When we put __declspec(dllexport) before any class name, compiler treats this class
to be used by external program. Thus it should create an import library. One .lib file will be
created after compilation of the module with name as <module name>.lib.

External executable can link this class by including this import library and prototype heared.
Prototype header syntax should be
Syntax: class __declspec(dllimport) <class name>;
Example:
class __declspec(dllimport) CExportClass1
{
void Function1(void);
};
Please note the __declspec(dllexport) keyword has been replaced with __declspec(dllimport).

For this class import, symbols that are exported are like the following
Class CExportClass1, symbol - ??4CExportClass1@@QAEAAV0@ABV0@@Z
Class function Function1, symbol- ?Function1@CExportClass1@@AAEXXZ

How can I call a function of a DLL file?

Application can call a DLL function in two ways.

• Implicit Call
• Explicit Call

Implicit Calling: When application or client uses its import table to call the external
symbol/functions, it is called implicit call. In implicit call application use prototype header and
import library to link an external symbol.
Example:
Suppose math library has a import function add()

#include "math.h"
int c = add(a, b);

Explicit Calling: When application does not links the external symbol by import library rather it
loads the DLL at runtime. It does the same mechanism as operating system does during loading
of the implicit linked DLL calls.

This is done by using Win32 APIs like :

• LoadLibrary() - loads and links a input library form the DLL path, or current path,
• GetProcAddress() - finds the symbol/function address by its name for a loaded DLL
• FreeLibrary() - unloads the loaded DLL instance

/*Example of Explicit Call*/


typedef (add_proc)(int a, int b);
int main(int argc, char *argv[])
{
add_proc *add;
HANDLE h_dll;
int a = 1, b = 2, c;
h_dll = LoadLibrary("math.dll");/*Explicit Load*/
if(h_dll)
{
add = GetProcAddress(h_dll, "add");
if(add)
{
c = add(a, b); /*Explicit Call*/
}
else
{
printf("add() not found in math.dll");
}
FreeLibrary(h_dll);
}
else
{
printf("Unable to load math.dll");
exit(-1);
}
}

When ever we execute an EXE, one application instance is created for each
execution. Is it true for DLL also? How many instance of a DLL is created if a
DLL is loaded from 5 different applications? Explain.

Let us first examine the entry point of Application and a Dynamic Link library.
Application WinMain() entry point

Prototype:

BOOL WINAPI WinMain(HINSTANCE hInstance,


HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd);
Return value: 0 for success, non zero for error.
hInstance - Current instance handle of the application
hPrevInstance - Previous instance handle of the application
lpCmdLine - command line argument string
nShowCmd - top window show attribute

DLL entry point DllMain()


Prototype:

BOOL APIENTRY DllMain( HANDLE hModule,


DWORD ul_reason_for_call,
LPVOID lpReserved);
Return value: 0 for success, non zero for error.
APIENTRY tells the compiler that it is an external/exported function.
hModule - This is the instance handle of the Loaded DLL.
ul_reason_for_call - reason for calling this DllMain() from Win32 subsystem
lpReserved - reserved variable.

Now from the above description it is clear that when we execute an EXE OS creates an instance
handle and passes by hInstance argument. For next creation it passes current instance handle to
hInstance and previous instance by hPrevInstance. Thus every time a new application instance is
created, OS creates a new instance for it.

This is not true for dynamic link library. From the entry point it is clear that it only has one
instance handle hModule and Win32 subsystem calls this function every time with a valid reason
via ul_reason_for_call. Reasons are new process attachment, process detachment, new thread
attachment and thread detachment.

DLL code is common thus there is no need to load it every time an application launches. OS
maintains a single loaded instance through out the lifetime even if more than one process loads
it. It reduces memory usage at runtime. When there is no application that uses a particular DLL
or all the client applications are terminated then OS unloads the DLL from memory.

How a DLL comes to know that it has been loaded by one application as well
as unloaded by it?

DllMain() is the main callback interface to talk to the Win32 subsystem. Rather we can say
Win32 subsystem talks to the DLL through DllMain() interface. Now please look at the short
description of the DllMain() callback routine as below.

Prototype:

BOOL APIENTRY DllMain( HANDLE hModule,


DWORD ul_reason_for_call,
LPVOID lpReserved);
Return value: 0 for success, non zero for error.
APIENTRY tells the compiler that it is an external/exported function.
hModule - This is the instance handle of the Loaded DLL.
ul_reason_for_call - reason for calling this DllMain() from Win32 subsystem
lpReserved - reserved variable.

ul_reason_for_call can have the following values

1. DLL_PROCESS_ATTACH, value 1
2. DLL_THREAD_ATTACH, value 2
3. DLL_THREAD_DETACH, value 3
4. DLL_PROCESS_DETACH, value 0

From the argument value it is clear that ul_reason_for_call will have the value
DLL_PROCESS_ATTACH when a new process attaches to DLL.
Also ul_reason_for_call = DLL_PROCESS_DETACH when a process terminates.

How Win32 sub-system informs the DLL when the application creates a
thread?
The entry point function DllMain() is the main callback interface for achieving this mechanism.
We have to look into the prototype and description of arguments of DllMain()

Prototype:

BOOL APIENTRY DllMain( HANDLE hModule,


DWORD ul_reason_for_call,
LPVOID lpReserved);
Return value: 0 for success, non zero for error.
APIENTRY tells the compiler that it is an external/exported function.
hModule - This is the instance handle of the Loaded DLL.
ul_reason_for_call - reason for calling this DllMain() from Win32 subsystem
lpReserved - reserved variable.

ul_reason_for_call can have the following values

1. DLL_PROCESS_ATTACH, value 1
2. DLL_THREAD_ATTACH, value 2
3. DLL_THREAD_DETACH, value 3
4. DLL_PROCESS_DETACH, value 0

From the argument value it is clear that ul_reason_for_call will have the value
DLL_THREAD_ATTACH when a new thread attaches to the current process.
Also ul_reason_for_call = DLL_THREAD_DETACH when a thread terminates from the
process.

What are AFX Extension class and Extension DLLs?

Regular DLLs allows us to use MFC in the exported functions, but they do not require that the
calling application should also use MFC. Thus regular DLL can be easily used in programs
developed in other Windows programming languages like Visual Basic or Delphi. A big
restriction of regular DLL is that it cannot export C++ classes. This restriction has been lifted in
an Extension DLL. In an Extension DLL we can export classes. This forces the client application
to be MFC application. The client can construct object of the exported class or derive classes
from it. An extension DLL should meet two requirements:

1. An extension DLL dynamically links to the code in the MFC DLL. Hence an extension
DLL requires that the client program be dynamically linked to the MFC library.
2. Both the client program and the extension DLL be synchronized to the same version of
the MFC DLLs.

Example:

Class AFX_EXT_CLASS CMyAboutBox: public CDialog


{
Public : void ShowDialog(void);
};

For imports we use dllimport and for export we use dllexport keyword. MFC
uses only one keyword AFX_EXT_CLASS, how can that be possible?

For normal class or function when we imported or exported has to go with two prototypes.

Exporting: When use in DLL project our prototype should be.


class __declspec(dllexport) CMyAboutBox;

Importing: When we are using in an application our prototype should be.


class __declspec(dllimport) CMyAboutBox;

For MFC we use only one common prototype i.e.


class AFX_EXT_CLASS CMyAboutBox;

AFX_EXT_CLASS macro is actually defined in two way for two projects thus we are able to use
only one prototype.

Definitions are like the following:

// for classes
#ifndef AFX_CLASS_EXPORT
#define AFX_CLASS_EXPORT __declspec(dllexport)
#endif
#ifndef AFX_CLASS_IMPORT
#define AFX_CLASS_IMPORT __declspec(dllimport)
#endif
#ifdef _AFXEXT
#define AFX_EXT_CLASS AFX_CLASS_EXPORT
#else
#define AFX_EXT_CLASS AFX_CLASS_IMPORT
#endif

When we are using a DLL project _AFXDLL and _AFXEXT are defined in preprocessors in the
project settings thus the resultant expanded form is
Class __declspec(dllexport) CMyAboutBox;

For Application project _AFXEXT macro is not defined thus


thus the resultant expanded form is
class __declspec(dllimport) CMyAboutBox;

How we use dynamic linking in Linux? Give example.


Linux like Windows also supports all the linking of Windows. We shall discuss all the topics one
by one briefly.

Static Linking:
Let us consider math.c file. We want to make it as a static library.
First we compile it with position independent flag on(-fPIC). This is needed for dynamic/static
linking.
$cc -fPIC -c math.c

Now make a archive or static lib with the object file.


$ar rc libmath.a math.o

To use this static library in a application we need to do the following steps:

1. compile the application code (place math.h in include folder)


$cc -c app.c -Iinclude -o app.o
2. Link with static library math.a
$ld app.o libmath.a -o app
3. Run the application
$./app

Implicit Dynamic Linking:


Let us consider once again math.c file for dynamic linking. We want to make it as a dynamic
library. First we compile it with position independent flag on(-fPIC). This is needed for
dynamic/static linking.
$cc -fPIC -c math.c

Now make a shared library with the object file.


$cc -shared libmath.so math.o

To use this shared library in a application we need to do the following steps:

1. compile the application code (place math.h in include folder)


$cc -c app.c -Iinclude -o app.o
2. Link with import library math.lib
$ld app.o -lmath -o app
3. Copy the libmath.so in lib path or current path and run the application
$./app

Explicit Dynamic Linking:


Let us consider once again math.c file for explicit linking. The steps for creating a shared library
are same as that of implicit linking.
First we compile it with position independent flag on(-fPIC). This is needed for dynamic/static
linking.
$cc -fPIC -c math.c

Now make a shared library with the object file.


$cc -shared libmath.so math.o
To use this shared library in a application we need to load the library then find the function
pointer address, invoke the function, and at last unload the library.
Linux provides some dynamic link library APIs to achieve this. Her are some useful frequently
use APIs:

• dlopen() - loads a dynamic link binary


• dlsym() - returns the function pointer if found the function entry
• dlclose() - unloads the dynamic link binary

How we use dynamic linking in Linux? Give example.

Linux like Windows also supports all the linking of Windows. We shall discuss all the topics one
by one briefly.

Static Linking:
Let us consider math.c file. We want to make it as a static library.
First we compile it with position independent flag on(-fPIC). This is needed for dynamic/static
linking.
$cc -fPIC -c math.c

Now make a archive or static lib with the object file.


$ar rc libmath.a math.o

To use this static library in a application we need to do the following steps:

1. compile the application code (place math.h in include folder)


$cc -c app.c -Iinclude -o app.o
2. Link with static library math.a
$ld app.o libmath.a -o app
3. Run the application
$./app

Implicit Dynamic Linking:


Let us consider once again math.c file for dynamic linking. We want to make it as a dynamic
library. First we compile it with position independent flag on(-fPIC). This is needed for
dynamic/static linking.
$cc -fPIC -c math.c

Now make a shared library with the object file.


$cc -shared libmath.so math.o

To use this shared library in a application we need to do the following steps:

1. compile the application code (place math.h in include folder)


$cc -c app.c -Iinclude -o app.o
2. Link with import library math.lib
$ld app.o -lmath -o app
3. Copy the libmath.so in lib path or current path and run the application
$./app

Explicit Dynamic Linking:


Let us consider once again math.c file for explicit linking. The steps for creating a shared library
are same as that of implicit linking.
First we compile it with position independent flag on(-fPIC). This is needed for dynamic/static
linking.
$cc -fPIC -c math.c

Now make a shared library with the object file.


$cc -shared libmath.so math.o

To use this shared library in a application we need to load the library then find the function
pointer address, invoke the function, and at last unload the library.
Linux provides some dynamic link library APIs to achieve this. Her are some useful frequently
use APIs:

• dlopen() - loads a dynamic link binary


• dlsym() - returns the function pointer if found the function entry
• dlclose() - unloads the dynamic link binary

Sample code:
#include<dlfcn.h>
typedef int (add_func) (int a, int b);

void *lib_handle = NULL;


add_func * add;
int main (int argc, char *argv[])
{
lib_handle = (void *)dlopen("libmath.so", RTLD_LAZY);
if(lib_handle)
{
add = dlsym(lib_handle, "add");
if(lib_func)
{
printf("1 + 2 = %d", add(1, 2));
}
else
{
printf("Function entry not found in DLL");
}
dlclose(lib_handle);
}
else
{
printf("Unable to open DLL");
}
}
What is resource DLL? When and how we can use it?

Resource DLL are those which contains recourse related to binary and no source code. Resource
DLL can contain the followings

1. Accelerators
2. Bitmaps
3. Icons
4. Cursors
5. Menus
6. Dialogs
7. HTMLS
8. String Tables
9. Toolbars
10. Versions

Resource DLL can holds resources that can be shared between many applications and thus
minimizes the size of each applications.

Resource DLLs are loaded using LoadLibrary() and the with MFC API AfxSetResourceHandle()
we set the loaded resource DLL instance as our current resource instance. All the call of loading
a resource line LoadIcon() etc. will now be loaded from the resource DLL.

Necessary MFC APIs:

• HINSTANCE AFXAPI AfxGetResourceHandle() - Returns the current loaded resource


handle.
• void AFXAPI AfxSetResourceHandle(HINSTANCE hInstResource) - Sets the new
resource handle for the MFC Application.

Das könnte Ihnen auch gefallen