静态库和动态库

来源:互联网 发布:java的命名规范 编辑:程序博客网 时间:2024/06/06 13:11
静态库和动态库
1、extern和static
1)函数
编译器在处理函数调用代码时需要函数原型,否则会根据函数调用代码做隐式声明,造成参数不一致!
extern关键字声明函数,表示不同源文件的函数是同一个,可写在函数体内
static关键字声明函数,表示只在该文件可见,其它不可用
2)变量
同函数,只是对于变量,extern关键字不可以省略!

2、头文件
头文件中的变量和函数声明一定不能是定义,否则可能出现重定义!
1)角括号和引号
角括号:先查找-I选项指定目录,然后查找系统的头文件目录
引号:先查找包含头文件的.c文件所在的目录,然后查找-I选项指定目录,然后查找系统的头文件目录

2)相对路径
在#include预处理使用相对路径
例:#include"stack/stack.h"

3)避免重复
#ifndef、#define和#endif
①重读可能导致预处理速度变慢
②typedef和struct不允许重复

3、静态库
库文件名都是以lib开头的,静态库以.a作为后缀
1)ar rc libstack.a stack.o push.o pop.o
ar命令类似于tar命令,选项r表示后面的文件列表添加到文件包
2)gcc main.c -o main ./libstack.a

4、动态库
1)gcc -shared -fPIC -o libtest.so test.c
-shared表示动态库,-fPIC表示生成位置无关
2)gcc main.c -o main ./libstack.so
ldd main查看编译依赖

5、回调函数
如果参数是一个函数指针,调用者可以传递一个函数的地址给实现者,让实现者去调用它
示例:void func(void (*f)(void *), void *p);
1)para_callback.h
#ifndef PARA_CALLBACK_H
#define PARA_CALLBACK_H
typedef void (*callback_t)(void *);
extern void repeat_three_times(callback_t, void *);
#endif
2)para_callback.c
#include"para_callback.h"
void repeat_three_times(callback_t f, void *para)
{
   f(para);
   f(para);
   f(para);
}
3)main.c
#include<stdio.h>
#include"para_callback.h"
void say_hello(void *str)
{
    printf("hello %s\n", (const char *)str);
}
int main()
{
    repeat_three_times(say_hello, (void *)"Guys");
    return 0;
}