link library Dynamic link library detailed introduction to _c language

Source: Internet
Author: User
Tags export class
In Windows, there are two types of link libraries: Static link libraries. lib and dynamic link library. dll. Where a dynamic-link library is used, it usually provides a. lib, called the introduction library, which mainly provides functions and symbolic names exported by the DLL, allowing the link to find the corresponding function mappings in the DLL.
The static link library and the dynamic link library are similar in that they are resources that are made available to other programs to invoke. Where dynamic-link library invocation methods are called implicitly (static import calls) and display calls (dynamic import calls).

Compiling Environment
Microsoft Visual Stdio 2010
--------------------------------------------------------------------------------
DLL export symbol
example, first generate a Dll1.dll and dll1.lib
Copy Code code as follows:

DLL1 Engineering, Dll1.cpp
_declspec (dllexport) is an exported symbol
_declspec (dllexport) int Add (int a, int b)
{
return a + B;
}

Using Microsoft's depends tool to view dll1.dll, the exported symbols are as follows:

The meaning of each field: Ordinal (symbol number, followed by the use of GetProcAddress, reference value), Hint (this I am not too clear, is said to be not understand), function (this is the function of the export of the symbolic name), EntryPoint (This is the address of the function in the DLL).
The function name becomes this way because the compiler used is compiled by default in C + +, and because C + + supports overloading, additional symbols need to be added to the function name to differentiate it from overloaded functions of the same name in order to navigate through the symbol name in the DLL.
Here you can do a simple test, the new console test project Dlltest as follows.
Copy Code code as follows:

Dlltest Engineering, DllTest.cpp
#include <iostream>
using namespace Std;
int main (void)
{
extern int Add (int a, int b);
_declspec (dllimport) is an import declaration, which is more effective than the above, while the compiler can compile more efficient code.
_declspec (dllimport) int Add (int a, int b);
cout << Add (1,2) << Endl;
GetChar ();
return 0;
}

Compile link, hint link error lnk2019:unresolved external symbol "__declspec (dllimport) int cdecl Add (int,int)" (__imp_? add@ @YAHHH @z) referenced in function _main, it is obvious that the compiler, when compiling, renames the Add function and looks like the one above with depends. It means that the definition of this symbol is not found.

Add code as follows: (Note that my output directory for both projects is in the same directory as the solution, Debug, in order to avoid every modification of the Lib file, directly using the relative path declaration.) )
Copy Code code as follows:

Dlltest Engineering, DllTest.cpp
#include <iostream>
using namespace Std;
#pragma comment (lib, "...). /debug/dll1.lib ")///Display declaration to link dll1.lib, implicitly invoke
int main (void)
{
extern int Add (int a, int b);
_declspec (dllimport) is an import declaration, which is more effective than the above, while the compiler can compile more efficient code.
_declspec (dllimport) int Add (int a, int b);
cout << Add (1,2) << Endl;
GetChar ();
return 0;
}

After the compilation is run, use the Depends tool to view the input information that is dependent on the DllTest.exe as follows:

It can be seen that DllTest.exe through the dll1.lib, introduced to the dll1.dll dependence.

--------------------------------------------------------------------------------

DLL-supplied header file
Normally, when you get a. dll, we don't know what function calls it provides (exactly, it should be the way it is called). Because we can use the depends tool to view the DLL exported functions and their sequence number, of course, there may be other ways to know how to use the specific, but certainly not know the details of the implementation of the internal. So that, for ease of use, a. h file that is supposed to be a DLL is usually provided to declare information such as the way and description it provides to the client. The client uses the header file to import the interface that is being used. However, in order to avoid the declaration of these functions in many places, it is common for the client to import all interfaces directly in the. h file and use them as an export when the DLL is compiled. The method is as follows:
Copy Code code as follows:

DLL1 Engineering, Dll1.h
#ifndef DLL1_API
#define DLL1_API _declspec (dllimport)
#endif
The above code indicates that if no DLL1_API macros are defined before the header file is included, then all subsequent DLL1_API macros are expanded to _declspec (dllimport), that is, import.
Because typically the client does not define the macro (assuming that the macro is not defined by other files in the client), the client uses the header file for import.
DLL1_API int Add (int a, int b);

Copy Code code as follows:

DLL1 Engineering, Dll1.cpp
#define DLL1_API _declspec (dllexport)
Note that the above line, before the header file is included, defines the DLL1_API macro so that the Dll1_api in the header file is expanded to _declspec (dllexport), thus declaring the function as an export.
#include "Dll1.h"
The function of exporting declarations in a header file is no longer declared exported.
int add (int a, int b)
{
return a + B;
}

Accordingly, the Testdll project contains. h files, and no longer has to be stated.
Copy Code code as follows:

Dlltest Engineering, DllTest.cpp
#include <iostream>
using namespace Std;
#include ". /dll1/dll1.h "//contains the header file, there is no need to declare it later.
#pragma comment (lib, "...). /debug/dll1.lib ")///Display declaration to link dll1.lib, implicitly invoke
int main (void)
{
cout << Add (1,2) << Endl;
GetChar ();
return 0;
}

This basically explains why the DLL is usually referenced when there is a header file, and the header file has a lot of #ifndef and so on stuff.

--------------------------------------------------------------------------------
Dynamic link Library Export class
Of course, the dynamic link library can also export classes, note that the way to declare the class Dll1_api csample, rather than Dll1_api class csample.
Also, note that when you export a class, all of its member functions are also exported, but you still follow the class member variable access permission restrictions.
If you export the member functions of a class separately (declaratively and globally), you can instantiate the class object at the client and call the exported member function, not the exported member function (even public).

--------------------------------------------------------------------------------
An adapted symbol name.
When you export a symbol, it is said that C + + will adapt the function name to support the function overload. Then there is a problem, if the use of C + + compiler (resulting in a different symbol name is compiled) or the client uses the C compiler call, there will be LNK2019 such a link error, can not find the symbol. This problem greatly limits the scope of use of DLLs.
Workaround 1:
using extern "C" (note that C must be capitalized), the front statement indicates that the function compiles the link in C mode. C-Way compile the connection exported function does not adapt the symbol name, so you can avoid the above problems.
Copy Code code as follows:

DLL1 Engineering, Dll1.h
#ifndef DLL1_API
#define DLL1_API extern "C" _declspec (dllimport)
#endif
The above code indicates that if no DLL1_API macros are defined before the header file is included, then all subsequent DLL1_API macros are expanded to _declspec (dllimport), that is, import.
Because typically the client does not define the macro (assuming that the macro is not defined by other files in the client), the client uses the header file for import.
DLL1_API int Add (int a, int b);
Class Csample
//{
Public
DLL1_API int substract (int a,int b);//In this case, the class member function is exported, the compiler cannot pass the
//};

Note here that both. h and. cpp have to add extern "C" so that both import and export are compiled in C.
Copy Code code as follows:

DLL1 Engineering, Dll1.cpp
#define DLL1_API extern "C" _declspec (dllexport)
Note that the above line, before the header file is included, defines the DLL1_API macro so that the Dll1_api in the header file is expanded to _declspec (dllexport), thus declaring the function as an export.
#include "Dll1.h"
The function of exporting declarations in a header file is no longer declared exported.
int add (int a, int b)
{
return a + B;
}
//
int csample::substract (int a,int b)
//{
return a-b;
//}

Then use depends to view:

The exported function symbol name is the same as the function declaration. Because the client is used, the import is also used in the extern "C" way, so the client when compiling the link, also uses the function original name symbol.
shows that a C + + class and member function export cannot be used in this way, because of the way in which it is compiled with the method of compiling links.
Also, if we add a standard calling convention to a function declaration: Dll1_api int _stdcall Add (int a, int b); (Note that you also add _stdcall to the definition of the function). The compiled result uses depends to view the symbol name _add@8, which means that the symbol names are changed again.
Workaround 2:
Use the module definition file. Def, the format specification for this file view MSDN, search for. def. Where the library command is used to name the DEF file for export of the library file, exports is used for named export function symbol names. In other words, the. def file is primarily used to control information such as export symbols.
Copy Code code as follows:

LIBRARY DLL1
Exports
Add11=add

Here I give the Add function alias Add11, note that you also need to declare add as Add11 in the. h file (the function is to provide the client use, of course, can also directly in the client declaration function as ADD11, if you know the definition of the function, etc.). Once the. Def is provided, any calling conventions provided in. cpp are no longer valid because. DEF specifies the generated symbol name. As long as it is understood here,. def controls the export symbols of the DLL, which, when used by the client, can be used whenever a declaration is provided and the. lib file is linked.
Add: The VC6.0 IDE will need to specify a. def file in the input-module define file of link options, which the compiler uses to use this. def file.

Note:
This piece about the calling convention, plus no extern "C", I am still quite confused. After the understanding, and then come here to add, welcome to the audience to provide me with this piece of relatively good introductory information.

--------------------------------------------------------------------------------
Show links (dynamic import links)
As mentioned earlier, let the exported function have no name, so how does the client invoke it? is to use the ordinal in the symbol table (which can be viewed through the tool), or you can use the name of the function to import. Dynamic imports do not require LIB files and. h Files (if you know the name of the function).
Copy Code code as follows:

Dlltest Engineering, DllTest.cpp
#include <iostream>
using namespace Std;
#include <windows.h>
int main (void)
{
Hmodule hmodule =:: LoadLibraryA ("Dll1.dll");
if (NULL!= hmodule)
{
typedef int (*ADDPROC) (int a, int b);
Addproc add = (addproc):: GetProcAddress (hmodule, "add11"); Import by Function name
Addproc add = (addproc):: GetProcAddress (Hmodule, Makeintresourcea (1)); By ordinal import, note that the second parameter should be placed in a low byte position at this point, as described in the MSDN instructions.
if (NULL!= Add)
cout << Add (1,1) << Endl;
:: FreeLibrary (hmodule);
}
GetChar ();
return 0;
}

It is worth mentioning that the dynamic import based on the function name is actually based on the symbol name, that is, the symbol name provided by the DLL is consistent with the function declaration provided to the user.

In addition, when dynamically importing a dynamic link library, the. exe is not able to see the required input information.

--------------------------------------------------------------------------------
PostScript
The first time to write so detailed and so long Bowen, can be seen to write to the back of the time has become more and more rough. Because when I wrote it later, I didn't know what to write, because if I extended it, there would be too many things to add. It is also partly due to the fact that what I understand later is not too thorough and very little used at the same time. Anyway, my mind is pretty messed up. Here to those who write blog to express deep admiration for the heroes.

Finally, I would like to affirm that these are my own reference video collation summed up, there must be no professional or even wrong place, I implore to provide guidance, I understand in learning, will be timely changes, thank you.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.