First, the problem arises.
Project wrote a logger, originally is code, everyone can be used alone, but later project integration, everyone's part into the Lib, and the front end will be logger packaged together into LIB, the background according to reason should not include. cpp files can also be used in logger, Because if the background is also included and compiled, it should be redefined with the logger in the front-end compilation unit.
But strangely, rather than redefining, instead of getting an IO stream on this side (flow is a static variable), it is inconceivable that the namespace is finally solved.
Although the problem was not solved perfectly, I decided to do a good bit of Lib and DLL, because only for logger:
Benefits 1 In this project, the log module is completely independent of the module, from the point of view of design, should be separated from the packaging, and then we can use this package together to achieve the loose coupling;
Benefits 2 logger into a lib or DLL, you can use the same as some API, not only for this project, the future of the laboratory projects can be used.
In addition, you can thoroughly engage in dynamic libraries and static libraries.
Two. Starting with the simplest definition
The simplest definition is also the most credible letter:
LIB and DLL
A Lib file is a collection of obj files.
Of course, there are some other ancillary information , which is intended to allow the compiler to accurately locate the corresponding obj file. We can operate the Lib file by Tlib.exe (root directory under tc2.0)
A DLL is a function implementation code that is loaded at run time and is considered by the individual to be the binary code of a part of the snippet assembly.
Static compilation and dynamic compilation
Note: I for static compilation and dynamic compilation concept after verification, there is no conclusion, first left white in this, and then updated after verification.
The following explanation is only personal understanding.
Dynamic compilation: Executables need to be accompanied by a dynamic link library that is loaded at run time by the dynamic link library
Static compilation: Link the attached static link library into the final executable, which is what is done during the compile time
Three. Static link library version Logger
I compiled environment: Win7 vs2013, static link library for Lib
1 Generating Lib
I want to make logger into a Lib for external links to call. Clarify the inclusion relationship as follows:
(1) logger.h contains mutex.h and some other header files
(2) mutex.h contains pthread.h, and is added to the code to #pragma comment(lib, "pthreadVC2.lib")
use third-party functions
namely: Logger.h-> mutex.h-> pthread.h
and Pthread provides pthread.h + Pthread related lib + pthread related DLLs
Positive start:
I found that if I chose to generate LIB, the compilation option could not add "additional dependencies", so I ventured to guess that the compiler guide link in the Code pthread Lib was not used to generate LIB.
Comment Compilation Guide statement, generate LIB Success ~ ~
This means that when the Lib is generated, it will not be linked, and will naturally not be redefined and externally defined checks, only the compilation unit of the current project to generate intermediate files (here is the. obj file) packaging, even if the code indicates the need to link the external lib.
That is, Lib cannot link external lib~~
Personally, the compiler does this to prevent many Lib from repeatedly defining the same external lib. And the generation Lib does not do the link, because Lib's ultimate function is to let the executable program to run, the generation of Lib link is meaningless.
2 external use Lib
Need to include the LIB generated in the previous step, using the #pragma comment(lib, "logger.lib")
completion
#include "logger.h"#pragma comment(lib, "logger.lib")int main(intchar *argv[]){ initLogger("whInfolog.txt""whWarnlog.txt""whErrolog.txt"false);//初始化日志文件 LOG2(_INFO,"first log"); return0;}
The compiler is configured as follows:
In particular, it is important to note that:
Since the previous step generates LIB, there is no Lib file containing Pthread, and at the end of the generation of the executable file, you must:
(1) contains Lib folder as library folder
(2) in the included header file with the Pthread lib file (here is mutex.h), use #pragma comment(lib, "pthreadVC2.lib")
or set additional dependencies in the project properties
(3) The pthread DLL is placed in the executable directory or in the environment variable
Then you can use it normally.
Four. Dynamic Library link library version Logger
Because it is the win platform, generating a dynamic library is a DLL
1 Generating DLLs
DLLs are implemented binary codes, run fashion loads, and naturally have an "additional dependencies" option in the project properties, which means that when the DLL is generated, it needs to be linked, and the DLL contains an implementation of the external LIB.
So here you need to include the Pthread Lib directory and #pragma comment(lib, "pthreadVC2.lib")
set additional dependencies using or in the project properties
In addition, due to the particularity of the DLL, the DLL needs to be exposed to the function interface outside the black box has a special wording, see the code:
/*** function: Log dll API loggerapi.h** date:2016-04-28** author:bill wang*/#ifndef _logger_api_h_#define _LOGGER_API_H_#include "logger.h"#define Wh_dll_exports#ifdef wh_dll_exports#define WH_DLL_API __declspec (dllexport)//Export#else#define WH_DLL_API __declspec (dllimport)//import#endifextern"C"{Wh_dll_apivoidApi_initlogger (ConstSTD::string& Info_log_filename,ConstSTD::string& Warn_log_filename,ConstSTD::string& Error_log_filename,BOOLIsappend =true);Wh_dll_apistd::ostream& Api_writelogger (log_rank_t rank,ConstSTD::stringReason);Wh_dll_apivoidEchotest ();//echo Test}#endif
/*** function: Log dll API loggerapi.cpp** date:2016-04-28** author:bill wang*/#include "loggerAPI.h"#include "logger.h"#include <iostream>using namespace STD;voidApi_initlogger (Const STD::string& Info_log_filename,Const STD::string& Warn_log_filename,Const STD::string& Error_log_filename,BOOLIsappend) {Initlogger (Info_log_filename, Warn_log_filename, Error_log_filename, isappend);//Initialize log file}STD::ostream& Api_writelogger (log_rank_t rank,Const STD::stringReason) {returnLOG2 (rank, reason);}//echo TestvoidEchotest () {cout<<"Echo success!!"<< Endl;}
Using Depends.exe to see the results below, you can see clearly that the DLL is given the function entry address of the exposed interface
2 Using DLLs Externally
//#include "loggerAPI.h"#include <Windows.h>#include <iostream>#include <string>using namespace STD;typedef enumLog_rank {_info, _warning, _error, _fatal}log_rank_t;typedef void(*api_initlogger) (Const STD::string& Info_log_filename,Const STD::string& Warn_log_filename,Const STD::string& Error_log_filename,BOOLIsappend);typedef STD::ostream& (*api_writelogger) (log_rank_t rank,Const STD::stringReason);typedef void(*api_echotest) ();intMainintargcChar*argv[]) {hmodule HM =:: LoadLibrary (TEXT ("Logger.dll"));//If the DLL fails to load, release the resources it occupies if(HM = = NULL) {cout<<"HM is NULL"<< Endl; :: FreeLibrary (HM);return 0; } api_echotest main_echotest = (api_echotest):: GetProcAddress (HM,"Echotest");if(Main_echotest = = NULL) {cout<<"main_echotest is null"<< Endl; :: FreeLibrary (HM); } main_echotest (); Api_initlogger Main_api_initlogger = (Api_initlogger):: GetProcAddress (HM,"Api_initlogger"); Main_api_initlogger ("WhInfolog.txt","WhWarnlog.txt","WhErrolog.txt",false);//Initialize log fileApi_writelogger Main_api_writelogger = (Api_writelogger):: GetProcAddress (HM,"Api_writelogger"); Main_api_writelogger (_info,"First Log"); :: FreeLibrary (HM);return 0;}
If you are careful to find, I will comment on the above code, and #include "loggerAPI.h"
changed to include a lot of other header file and enumeration declaration, because the use of DLL is not necessary to include the implementation of all the DLL's header file, as long as the function pointer type is correct, all the variable type, you can get the function address, The reader can experiment on its own.
On both sides of the DLL, as long as the function signature is identical,
So this side does not contain the pthread.h, also does not contain the Pthread Lib library, but the pthread DLL still needs, because logger.dll in the link pthread Lib library, relies on the pthread DLL
Five. Refute
Today, while reading a blog post, found a lot of questions, the key is that this article is still high in the search list ...
http://blog.csdn.net/wuan584974722/article/details/7953213
Issue 1 Dynamic Lib is equivalent to an H file
The article repeatedly mentions "dynamic Lib equivalent to an H file, which is a declaration of the export portion of the implementation part (. dll file)"
we all know that DLLs to use, must be parsed, this parsing process is required within the function of the implementation , that is, Lib here as a broker. For example, a function is defined in Lib, which is void lib_resolveEchoTest()
specifically parsed in the DLL void EchoTest()
, and can then invoke the void lib_resolveEchoTest()
work in the completion DLL in Lib void EchoTest()
.
It is true that Lib is equivalent to a header file, but saying "is a declaration of the export portion of the implementation part (. dll file)" is problematic. You can say that Lib is parsing those DLLs to implement this lib, but not just the declaration, because Lib is a collection of obj, if only to declare what the compiler unit, and then where is the obj? Obviously, bloggers don't know each other very well.
Issue 2 static compilation can be extracted from the DLL using a partial to the final executable file, thus implementing a detach of the DLL
This really does not understand, DLL is loaded at runtime, when you can compile the time to extract the???????
In addition, the blogger engaged in a lot of, such as "Static compilation", "Dynamic compilation", "Static Lib", "dynamic Lib" the concept of the flow. Let alone whether bloggers fully understand these concepts, even if there is no such concept is a problem. It's a real nonsense.
Summary
Online to find some information, more and more feel these bottom knowledge, need to read professional books, because of the information on the Internet, we select more need to take critical eyes to see the problem
Resources
[1] http://blog.csdn.net/lushuner/article/details/25048465
[2] http://bbs.csdn.net/topics/390177392
Discussion of Lib and DLL initiated from a logger