lib 与 obj 文件的关系

来源:互联网 发布:mac系统剪切 编辑:程序博客网 时间:2024/06/02 09:09

在使用tc编写程序时,你或许对其中的*.lib文件产生疑问,这些lib文件有什么用途?

C 语言编程时,通常要建立一些用户函数。如果这些函数具有通用性,一般的方法是将它们作成头文件,当需要时用include”命令将其包含到源程序之中,以提高编程效率。但在特定的程序中一般仅使用这些函数的一部分,若用上述方法包含所有函数,编译器在编译的时候会把所有包含进的函数都进行编译,这无疑会使源程序变得庞大而难于理解,并会影响执行效率。建立用户目标模块库(lib文件)可以解决这个问题,你可以事先把有特定功能的通用的子函数集编译完成后生成的obj文件打入lib文件,当链接器tlink.exe在进行链接操作时,便只会把程序内部用到的通用函数所在的obj文件链接进来(已验证:不能定位到具体函数),这样生成的obj文件便会更精简,生成的exe文件也更小。

其实,一个lib文件是obj文件的集合。当然,其中还夹杂着其他一些辅助信息,目的是为了让编译器能够准确找到对应的obj文件。我们可以通过tlib.exe(在tc2.0下的根目录)来对lib文件进行操作,你可以把自己生成的obj文件通过tlib命令加入到一个lib文件中,也可以把lib文件内的obj文件进行删除操作,还可以把内部的obj文件给提取出来。明白了lib文件的大致结构以及对它的具体操作,在学习C语言的过程中,就会又多了一个切入点对C语言具体实现进行研究。

command下,把当前目录设置为tlib.exe所在目录,然后输入tlib命令回车,此时显示的内容就是对tlib命令的详细解释,语法如下:

Syntax: TLIB libname [/C] [/E] commands, listfile

libname      library file pathname

commands     sequence of operations to be performed (optional)

listfile     file name for listing file (optional)

A command is of the form: <symbol>modulename, where <symbol> is:

+            add modulename to the library

-            remove modulename from the library

*            extract modulename without removing it

-+ or +-     replace modulename in library

-* or *-     extract modulename and remove it

/C           case-sensitive library

/E           create extended dictionary

具体解释:

tlib libname [/C] [/E] commands, listfile

/C:大小写敏感标志。该选项不常用,此参数为可选项。

/E:建立扩展字典。建立扩展字典可以加速大的库文件的连接过程,此参数同样为可选项。

操作命令(可选项):

+   obj文件名 把指定obj文件添加到lib文件中

-   obj文件名 把指定obj文件从lib文件中删除

*   obj文件名 导出指定的obj文件(导出后对应的obj文件在lib文件内仍然存在)

-+ obj文件名 替换指定的obj文件(前提是在lib文件中存在与指定obj文件同名的obj

-* obj文件名 导出指定的obj文件(导出后把对应的obj文件从lib文件内删除)

lib文件中obj文件列表(可选项)

此参数说明了命令运行后,生成的对应lib文件的列表文件名。它记录了当前lib文件内obj文件列表。如果你新加入了一个obj文件,就能从生成的lst文件中找到对应的obj文件的名称,至于其它信息的具体含义,自己有时间再去研究。

给个简单的例子:

1:编写一个C程序,名称为goodluck.c,程序如下:

void goodluck()

{

printf("Good Luck To You!");   

}

2:通过tcc.exe(在tc根目录下)对上述文件进行编译,命令格式为:

tcc -c goodluck.c-c 代表只进行编译操作)

3:通过tlib命令把goodluck.obj添加到库文件(*.lib)cs.lib中。

tlib cs.lib + goodluck.obj, cs.lst

运行后用记事本查看cs.lst中的内容,查找goodluck,看是否已添加成功。

4:添加成功后,再写一个C程序show.c

main()

{

clrscr(); /*清屏*/

goodluck();

}

看到的结果便是屏幕显示“Good Luck To You!”  

obj:

目标文件,一般是程序编译后的二进制文件,通过链接器和资源文件链接后就成为exe文件(链接器将使用这些文件生成EXE文件)

obj只给出了程序的相对地址,而EXE是绝对地址。 

CPP对应的二进制代码格式,是未经重定位的!

lib:是若干个obj的集合,本质与obj相同! 

lib有静态lib和动态lib之分。

静态lib将导出声明和实现都放在lib中。编译后所有代码都嵌入到宿主程序.

动态lib相当于一个h文件,是对实现部分(.dll文件)的导出部分的声明。编译后只是将导出声明部分编译到宿主程序中,运行时候需要相应的dll文件支持.

lib文件是不对外公开的,不能查看一个编译过后的文件

静态库(lib)的调用需要头文件(#include ".h")和添加库文件(.lib),添加库文件可以利用开发环境添加,也可以代码添加:#pragma comment(lib,"lib//tlib.lib"

编程中,添加lib文件的常用办法有二个:

1、把*.lib放在VCLib目录中

2、修改project settingLink->Input中的Addtional library path,加入你的目录dll:是可实际运行的二进制代码,有定位代码的! 

DLL 是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL还有助于共享数据和资源。多个应用程序可同时访问内存中单个DLL 副本的内容。

DLL内的函数分为两种:

(1)DLL导出函数,可供应用程序调用;

(2)DLL内部函数,只能在DLL程序使用,应用程序无法调用它们

要导出 DLL 函数,您可以向导出的 DLL 函数中添加函数关键字,也可以创建模块定义文件 (.def) 以列出导出的 DLL 函数。

h:  是头文件,也可算是源代码,因为当CPP中用#include时,会把包含的文件的内容在CPP中扩展开!

h文件是用来编写函数(类,变量类型)原型声明的,通常dlllibobj的使用需要有h文件的配合,以获得二进制代码的原型声明!

 

原创粉丝点击