Академический Документы
Профессиональный Документы
Культура Документы
Ajay Singh
SE Trainee : C++
Index
Linking & Loading. Static Vs. Dynamic Libraries. DLLs in VC++.
Loading
Combining multiple object files and
library modules into a single reloadable executable file. (i.e. Addresses are relative to 0) Mapping addresses within file to physical memory addresses. Resolving names of dynamic library items.
Which one is better, static or dynamic? Construct some programs of different size linked in both versions to compare:
Executable Size Loading Time Running Time Number of System Calls Memory Usage
6000 4000 2000 0 0% 30% 60% 90% 100% Percentage of Static Libraries
12000 10000 8000 6000 4000 2000 0 0% 30% 60% 90% 100% Percentage of Static Libraries
Loading Time
16000 14000 12000 10000 8000 6000 4000 2000 0 Small Median Large
Running Time
60 50 40
Static Loading 30 Running 20
Number of
System Calls
200
Memory Usage
(Byte)
8000
6000
100
4000
Static Dynamic
50
2000
Five Instances
But Dynamic runs more slowly. Dynamic has more system calls.
Dynamic need more loading time.
DLLs in VC++
Dynamic-link library (DLL), is Microsoft's implementation of the Shared Library concept in the MS Windows and OS/2 Operating Systems. These libraries usually have file extension as DLL, OCX (for libraries containing ActiveX controls), or DRV (for legacy System Drivers). The file formats for DLL is, Portable Executable (PE). DLLs can contain Code, Data and Resources, in any combination.
Advantages of using DLLs: Saves memory and reduces swapping. Upgrades to the DLL are easier. Provides after-market support.. Supports multi-language programs. Provides a mechanism to extend the MFC library classes. Eases the creation of international versions (by using Resource DLLs).
TestDll.h #ifdef __cpluscplus // Automatically defined when C+ compiler is used. #define EXPORT extern "C" __declspec (dllexport) #else #define EXPORT __declspec (dllexport) #endif EXPORT void DllFunction ((LPCWSTR lpMsgText);
TestDll.cpp
EXPORT void DllFunction (LPCWSTR lpMsgText) { MessageBox (GetActiveWindow (), lpMsgText, _T("DllFunction"), MB_OK); }
extern C : makes a function-name in C++ have 'C' linkage (compiler does not mangle the name) so that client code can link to/use function using a 'C' compatible header file. extern "C" forces a function to have external linkage (cannot make it static). __declspec (dllexport) : allow the compiler to generate the exported names automatically and place them in a .lib file. This .lib file can then be used just like a static .lib to link with a DLL.
functions in DLL.
#include "..\\TestDll\\TestDll.h" #pragma comment (lib, "..\\Debug\\TestDll.lib")
TestDll.lib file can now be used just like a static .lib to link functions in DLL.
Calling DLL Function:
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: DllFunction (_T(Creating Your Window)); break;
Case WM_CREATE:
if ((hLibrary = LoadLibrary (_T(TestDll.DLL"))) == NULL) { MessageBox (hWnd, _T(TestDll.DLL can't be loaded."), 0, MB_ICONERROR); return -1L; } // else load functions from DLL. pfnShowMsg = (pFxnSHOWMSG) GetProcAddress (hLibrary, DllFunction); pfnShowMsg (_T(Its a run-time DLL.)); FreeLibrary (hLibrary);
TestDll.h
@ Load Time
#define DllExport __declspec (dllexport) class DllExport A { int m_nNum; public: A() : m_nNum (0) {} A(int n) : m_nNum (n) {} ~A() {} void SetNum (int n); int GetNum (void); };
YourApp.h
Include .h and .lib in a normal fashion
#include "..\\TestDll\\TestDll.h" #pragma comment (lib, "..\\Debug\\TestDll.lib") We can also locate TestDll.lib in Project Property.
YourApp.cpp
With DLL loaded at load time, use DLL class same way as youve defined the class in your application.
Eg.
A aObj; aObj.SetNum (2258); iClassData = aObj.GetNum ();
TestDll.cpp
void A::SetNum (int n) { m_nNum = n; } int A::GetNum (void) { return m_nNum; }
@ Run Time
Approach
#1
#define DllExport extern "C" __declspec (dllexport) class CSample { int m_nNum; public: CSample() : m_nNum(0) {} CSample(int n) : m_nNum(n) {} virtual ~CSample() {} // All exportable functions are declared to be virtual virtual void SetNum (int n); virtual int GetNum (void); virtual void OverloadedFx(void); virtual void OverloadedFx (int); static int m_siData; int m_iData; static int GetStaticData(); // { return m_siData; }// fx is inlined. }; // Now export methods to return CSample objects extern "C" __declspec (dllexport) CSample* CreateSampleObject_v (void); extern "C" __declspec (dllexport) CSample* CreateSampleObject_i (int n);
@ Run Time
Approach #2
TestDll.DEF
LIBRARY TestDll EXPORTS ConstructAi= ??0A@@QAE@H@ZPRIVATE ConstructAv= ??0A@@QAE@XZPRIVATE DestructA= ??1A@@QAE@XZPRIVATE GetNum= ?GetNum@A@@QAEHXZPRIVATE SetNum= ?SetNum@A@@QAEXH@ZPRIVATE
TestDll.cpp
void A :: SetNum (int n) { m_nNum = n; } Int A :: GetNum () { return m_nNum; }
Module DEFinition File provide the linker with information about exports, attributes, and other information about the program to be linked. Dependency Walker is a free utility that scans any 32-bit or 64-bit Windows module (exe, dll, ocx, sys, etc.) and builds a hierarchical tree diagram of all dependent modules. For each module found, it lists all the functions that are exported by that module.
YourApp.cpp
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HINSTANCE hLibrary; A* pDllClassObj; // Creating pointer to a member function type typedef void (A::*pFnConstructorOfAi) (int); typedef void (A::*pFnConstructorOfAv) ();// i : int, v : void typedef void (A::*pFnSetNumOfA) (int); typedef int (A::*pFnGetNumOfA) (void); switch (message) { case WM_CREATE: hLibrary = LoadLibrary (_T(TestDll.DLL)); pDllClassObj = (A*) _alloca (sizeof(A)); pFnConstructorOfAv pfnConsDefA = reinterpret_cast <pFnConstructorOfAv> (GetProcAddress (hTestLibrary, " ConstructAv")); pFnSetNumOfA pfnSetNum = reinterpret_cast < pFnSetNumOfA > (GetProcAddress (hTestLibrary, " SetNum")); pDllClassObj->pfnSetNum (2258); // and same way use rest of the class functions
@ Run Time
Suppose were loading DLL at run-time and have done something like: #define DllExport __declspec (dllexport) class DllExport DLLClass { }; We cant export overloaded functions with single name, since .DEF file must contain unique entries for C++ mangled (decorated) class member functions.
Static Data Member
o A static declared variable seems not to be consistent over DLL boundaries.
o The static member is not accessed directly by code in the calling application, only
through member functions of the class in the dll. o inline functions accessing the static member: Those functions will be inline expanded into the calling applications code making the calling application access the static member directly. That will violate the finding referenced above that static variables are local to the dll and cannot be referenced from the calling application.
Thank You!