1、.h头文件是编译时必须的,lib是链接时需要的,dll是运行时需要的。
头文件,是文本文件,通常只是用来【声明】常量、自定义类型、函数 静态链接库,是经过编译生成的二进制文件,具体【定义】是不可见的 打个比方: 静态链接库就好比一个电视机,你不知道电视机内部的具体结构是怎样的 头文件就好比一个电视机遥控器,提供接口,让你可以使用库
故而源程序中要想使用库,就必须包含该库的头文件;即,要想使用电视(库文件),就必须要有该电视的遥控器(接口,即头文件)
但是在使用时,不仅要包含lib库文件,还是要包含相应的头文件。
例如:要是用printf(),就应该在源程序中包含#include <stdio.h>一样。
2、静态链接库不同于动态链接库(*.dll),
4、静态链接库与动态链接库都是共享代码的方式,
如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了。
但是若使用 DLL,该 DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。
静态链接库和动态链接库的另外一个区别在于:
静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。
5、“每一个lib文件就是若干函数(假设只有函数)的定义”
lib库有两种,一种是包含了函数所在DLL文件和文件中函数位置的信息,称为导出库;
一种是包含函数代码本身,一般现有的DLL,用的是前一种库;
以前在DOS下的TC/BC等,是后一种库。包含函数原型声明的,是头文件(.h)。
“通过#include包含这些函数声明的头文件后,我们的应用程序就可以使用lib文件中的函数”
还要指定编译器链接相应的库文件。
在IDE环境下,一般是一次指定所有用到的库文件,编译器自己寻找每个模块需要的库;
在命令行编译环境下,需要指定每个模块调用的库。
6、“那他和直接给出那个函数定义的文件,比如.cpp文件,和头文件有什么区别,静态链接库有什么用”
cpp文件是源代码,库文件是编译后的二进制代码,比如你可以调用Windows的API,但是不能看到其源代码一样。
“还有不明白的是,静态链接库中的lib文件只要用到,则整个lib文件的内容都放进了exe文件中,那它是被编译进去还是链接的时候连接进去的呢?”
是在链接的时候将lib链接到目标代码中。
7、静态链接库(Lib)
在VC++6.0中new一个名称为libTest的static library工程,
并新建lib.h和lib.cpp两个文件,lib.h和lib.cpp的源代码如下:
//文件:lib.h
#ifndef LIB_H
#define LIB_H
extern "C" int add(int x,int y); //声明为C编译、连接方式的外部函数,意思就是add()函数要用c编译器来编译,它在其它的.cpp源文件中定义。
#endif
//文件:lib.cpp
#include "lib.h"
int add(int x,int y)
{
return x + y;
}
编译这个工程就得到了一个.lib文件,这个文件就是一个函数库,它提供了add的功能。
将头文件和.lib文件提交给用户后,用户就可以直接使用其中的add函数了。(注意提交的是.h头文件和.lib文件,二者都要给,而不是仅仅提供.lib文件)
标准Turbo C2.0中的C库函数(我们用来的scanf、printf、memcpy、strcpy等)就来自这种静态库。
但是在使用时,不仅要包含lib库文件,还是要包含相应的头文件。
例如:要是用printf(),就应该在源程序中包含#include <stdio.h>一样。
8、下面来看看怎么使用这个库,在libTest工程所在的工作区内new一个libCall工程。
libCall工程仅包含一个main.cpp文件,它演示了静态链接库的调用方法,
其源代码如下:
#include <stdio.h>
#include "..\lib.h"//不可丢失 ,头文件不可丢
#pragma comment( lib, "..\\debug\\libTest.lib" ) //指定与静态库一起连接
int main(int argc, char* argv[])
{
printf( "2 + 3 = %d", add( 2, 3 ) );
}
静态链接库的调用就是这么简单,或许我们每天都在用,可是我们没有明白这个概念。
代码中#pragma comment( lib , "..\\debug\\libTest.lib" )的意思是指本文件(即main.cpp)生成的.obj文件应与libTest.lib一起连接。