一。预编译过程将程序中引用的头文件包含在源文件中,并对一些宏进行替换。
二。编译过程将用户可识别的语言翻译成一组处理器可识别的操作码,生成目标文件,通常翻译成汇编语言,而汇编语言通常和机器码之间是一种一对一的关系。
三。链接将所有的目标文件通过某种方式组合起来。生成可执行文件。目标文件中通常仅解析了文件内部的变量和函数,对于引用的函数和变量还没有解析,这就需要将其他已经写好的目标文件引用进来将没有解析的变量和函数进行解析,通常引用的目标是库。链接完成后会生成可执行文件。
[目标文件:是指经过编译器的编译生成的CPU可识别的二进制代码,但是目标文件一般不能执行,因为其中的一些函数过程没有相关的指示和说明。]
[可执行文件:是目标文件与相关的库链接后的文件,它是可执行的。]
gcc -c -o myfile.o demo.c //用于生成demo.c的目标文件,且被命名为myfile.o,因为.o是目标文件的扩展名,-c用于生成目标文件,-o用于指定要被命名的名字。
gcc -E demo.c //用于查看预处理后的文件内容。
gcc -S demo.c //对demo.c预编译后进行编译,生成.s扩展名的文件。
gcc -Idir //I为i的大写,表示用dir作为一个寻找头文件的目录,搜索路径为dir->/usr/include-->/usr/local/include
gcc -Ldir//表示将dir目次作为第一个寻找库文件的目次,寻找的次序是:dir-->/lib-->/usr/lib-->/usr/local/lib
gcc -lworld//l为L的小写,表示在-L指定的路径中去查找指定的动态链接库libworld.so,若在编译中加入参数-static,表示寻找的是静态链接库libworld.a
建立静态库,可以用ar程序,如
ar -rcs demolib.a demo.o //将demo.o目标文件放到demolib库中。
在需要的时候,比如main.c中用到了funlib.a中的函数,可以这样编译
gcc -o myDemo main.c funlib.a 即可
gcc dynloadfun.c -o dyn -ldl
注意:
一。要编译引用了动态链接库的源代码文件,步骤有3个
1。gcc -shared -Wl,-soname,libwandan.so -o libwandan.so.1 func.c
创建动态连接库文件。用-soname,mylibname 去注明要生成的别名
2。sudo ldconfig ~/CTest/
加入动态链接库缓存文件中。
3。gcc -o wandan main.c -lwandan -L./
编译,指定动态链接库文件,并指明所在目录
4。./wandan
二。在代码中动态调用动态链接库的函数时,在编译时
1。gcc -shared -Wl,-soname,libwandan.so -o libwandan.so.1 func.c
创建动态连接库文件。用-soname,mylibname 去注明要生成的别名
2。sudo ldconfig ~/CTest/
加入动态链接库缓存文件中。
3。gcc dynloadfun.c -o dyn -ldl
加上-ldl,表明需要引用动态链接库
三。除了上面gcc用到的参数外,比较常用的还有。
-I :表示将头文件的搜索路径变大 ,如-Idir
-L:表示将动态链接库的搜索路径变大,如-Ldir
四。既可以在编译时链接动态库也可以在程序中,即运行时候动态加载动态链接库文件,指定调用函数。
[编译时指定:要指定动态库的路径,并且需要指定动态库的名称。]
[运行时加载:只要在编译的时候加-ldl参数即可。]
通过man dlopen 可以看到帮助手册中有:
#include <dlfcn.h>
void *dlopen(const char *filename, int flag);
char *dlerror(void);
void *dlsym(void *handle, const char *symbol);
int dlclose(void *handle);
Link with -ldl. //表明链接时候直接加参数-ldl即可。
例子:
#include <dlfcn.h>
#include <stdio.h>
//动态加载库
int main(void)
{
char str[] = "Hello , I am coming!";
int (*pFunc)(char *str); //声明一个函数指针,在打开动态库的函数中要用到
void *pHandle = NULL; //库句柄
char *perr = NULL; //错误信息指针
pHandle = dlopen("/home/filson/CTest/libstr.so",RTLD_LAZY);
if(!pHandle)
{
printf("Failed to load the dynamic library\n");
return -1;
}else
{
printf("Success to load the dynamic library\n");
}
perr = dlerror();
if(!perr)
{
printf("Success\n");
}else
{
printf("errors\n");
return -1;
}
pFunc = dlsym(pHandle , "CalcStringLength");
perr = dlerror();
if(!perr)
{
printf("Success\n");
}else
{
printf("errors\n");
return -1;
}
printf("the string length = %d\n",pFunc(str));
dlclose(pHandle);
return 0;
}