再次温习运行时库
来源msdn:
This topic discusses the various .lib files that comprise the C run-time libraries as well as their associated compiler options and preprocessor directives.
The following libraries contain the C run-time library functions.
C run-time library (without iostream or standard C++ library) | Characteristics | Option | Preprocessor directives |
---|---|---|---|
LIBC.LIB | Single-threaded, static link | ||
LIBCMT.LIB | Multithreaded, static link | _MT | |
MSVCRT.LIB | Multithreaded, dynamic link (import library for MSVCR71.DLL). Be aware that if you use the Standard C++ Library, your program will need MSVCP71.DLL to run. | _MT, _DLL | |
LIBCD.LIB | Single-threaded, static link (debug) | /MLd | _DEBUG |
LIBCMTD.LIB | Multithreaded, static link (debug) | /MTd | _DEBUG, _MT |
MSVCRTD.LIB | Multithreaded, dynamic link (import library for MSVCR71D.DLL) (debug) | /MDd | _DEBUG, _MT, _DLL |
If you link your program from the command line without a compiler option that specifies a C run-time library, the linker will use LIBC.LIB.
To build a debug version of your application, the _DEBUG flag must be defined and the application must be linked with a debug version of one of these libraries. For more information about using the debug versions of the library files, see
This version of Visual C++ is not conformant with the C99 standard.
Standard C++ Library
Note that starting in Visual Studio .NET 2003, Visual C++ will no longer ship the old iostream libraries. For details, see
The new iostream functions, as well as many other new functions, exist in the Standard C++ Library:
Standard C++ Library | Characteristics | Option | Preprocessor directives |
---|---|---|---|
LIBCP.LIB | Single-threaded, static link | /ML | |
LIBCPMT.LIB | Multithreaded, static link | /MT | _MT |
MSVCPRT.LIB | Multithreaded, dynamic link (import library for MSVCP71.dll) | /MD | _MT, _DLL |
LIBCPD.LIB | Single-threaded, static link | /MLd | _DEBUG |
LIBCPMTD.LIB | Multithreaded, static link | /MTd | _DEBUG, _MT |
MSVCPRTD.LIB | Multithreaded, dynamic link (import library for MSVCP71D.DLL) | /MDd | _DEBUG, _MT, _DLL |
When you build a release version of your project, one of the basic C run-time libraries (LIBC.LIB, LIBCMT.LIB, and MSVCRT.LIB) is linked by default, depending on the compiler option you choose (single-threaded, multithreaded, or DLL). If you include a
#include <ios>
What is the difference between msvcrt.dll and msvcr71.dll?
The msvcrt.dll is now a "
What problems exist if an application uses both msvcrt.dll and msvcr71.dll?
If you have a .lib or .obj file that needs to link to msvcrt.lib, then you should not have to recompile it to work with the new msvcrt.lib in Visual C++ .NET. The .lib or .obj file may rely on the sizes, field offsets, or member function names of various CRT classes or variables, and those should all still exist in a compatible way. When you relink against msvcrt.lib, your final EXE and DLL image will now have a dependency on msvcr71.dll instead of msvcrt.dll.
If you have more than one DLL or EXE, then you may have more than one CRT, whether or not you are using different versions of Visual C++. For example, statically linking the CRT into multiple DLLs can present the same problem. Developers encountering this problem with static CRTs have been instructed to compile with /MD to use the CRT DLL. Now that the CRT DLL has been renamed to msvcr71.dll, applications may have some components linked to msvcrt.dll and others to msvcr71.dll. If your DLLs pass CRT resources across the msvcrt.dll and msvcr71.dll boundary, you will encounter issues with mismatched CRTs and need to recompile your project with Visual C++ .NET.
MathFun.h
1 #ifndef _MATHFUN_H_
2 #define _MATHFUN_H_
3
4 int AddNum(const int& a ,const int& b);
5
6 #endif
MathFun.cpp
#include "stdafx.h"
#include "MathFun.h"
int AddNum(const int& a ,const int& b)
{
return a+b;
}
1 #ifdef DLL_EXPORTS
2 #define DLL_API __declspec(dllexport)
3 #else
4 #define DLL_API __declspec(dllimport)
5 #endif
6
7 DLL_API int AddNumber(int a ,int b);
1 // dll.cpp : 定义 DLL 应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5 #include "dll.h"
6
7 #include "../LibMath/MathFun.h"
8 #pragma comment(lib ,"../debug/LibMath.lib")
9
10 #ifdef _MANAGED
11 #pragma managed(push, off)
12 #endif
13
14 BOOL APIENTRY DllMain( HMODULE hModule,
15 DWORD ul_reason_for_call,
16 LPVOID lpReserved
17 )
18 {
19 switch (ul_reason_for_call)
20 {
21 case DLL_PROCESS_ATTACH:
22 case DLL_THREAD_ATTACH:
23 case DLL_THREAD_DETACH:
24 case DLL_PROCESS_DETACH:
25 break;
26 }
27 return TRUE;
28 }
29
30 #ifdef _MANAGED
31 #pragma managed(pop)
32 #endif
33
34 DLL_API int AddNumber(int a ,int b)
35 {
36 return AddNum(a ,b);
37 }
1 // TestLibrary.cpp : 定义控制台应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5
6 #include "../LibMath/MathFun.h"
7 #pragma comment(lib ,"../debug/LibMath.lib")
8
9 int _tmain(int argc, _TCHAR* argv[])
10 {
11 int ret = AddNum(23,100);
12
13 printf("%d\n" ,ret);
14
15 ret = getchar();
16
17 return 0;
18 }
1 // TestLibrary.cpp : 定义控制台应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5
6 int _tmain(int argc, _TCHAR* argv[])
7 {
8 typedef int(*pAddNum)(int a,int b);
9 HINSTANCE hDLL;
10 pAddNum anum;
11 hDLL=LoadLibrary(L"DLL.dll");//加载动态链接库DLL.dll文件;
12 anum=(pAddNum)GetProcAddress(hDLL,"AddNumber");
13 int ret = anum(5,8);
14 FreeLibrary(hDLL);//卸载MyDll.dll文件;
15
16 printf("%d\n" ,ret);
17
18 ret = getchar();
19
20 return 0;
21 }
1 // TestLibrary.cpp : 定义控制台应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5
6 int _tmain(int argc, _TCHAR* argv[])
7 {
8 int ret = 0 ;
9
10 typedef int(*pAddNum)(int a,int b);
11 HINSTANCE hDLL;
12 pAddNum anum;
13 hDLL=LoadLibrary(L"DLL.dll");//加载动态链接库DLL.dll文件;
14 if (hDLL != NULL)
15 {
16 anum=(pAddNum)GetProcAddress(hDLL,"AddNumber");
17 if (anum != NULL)
18 ret = anum(5,8);
19 }
20 FreeLibrary(hDLL);//卸载MyDll.dll文件;
21
22 printf("%d\n" ,ret);
23
24 ret = getchar();
25
26 return 0;
27 }
【尽量组合运行时库来验证,如下】
调用静态库
结论:
静态库mtd,测试mdd出现2个警告,其来源于两个使用运行时库文件不一致
静态库mdd,测试mdd,完全通过,无警告;同样,两个设置成为mtd,也完全通过
静态库mdd,测试mtd,错误信息
静态库mdd,动态mdd,测试mdd,编译通过,运行成功(全部mtd也一样,区别在于生成文件大小,前者小很多)
静态库mdd,动态mtd,测试mdd,编译dll就通不过
无论生活、还是技术,一切都不断的学习和更新~~~努力~