linux库文件(静态库和动态库)
库libary
静态库在编译链接时就把库里的代码提取出来放入可执行文件中,程序执行是不再依赖哭,动态库在编译链接时只记录了要用的名字在哪个库文件中,运行是才从库文件中找这个名字(函数或者变量)并且访问它。可
执行文件大小、速度、库升级。
CPATH,C_INCLUDE_PATH这两个环境变量都可以用来指定gcc编译是的搜索的头文件的目录,类似-I选项。
gcc -c xxx2.c
写一个头文件xxx.h,里面放在这些函数和全局变量的声明。(extern int a;)
ar -r libxxx.a xxx1.o xxx2.o
CPATH,C_INCLUDE_PATH这两个环境变量都可以用来指定gcc编译是的搜索的头文件的目录,类似-I选项。
1)静态库(归档) libxxx.a
(1)写C语言程序(一般不应该有main函数)
gcc -c xxx1.cgcc -c xxx2.c
写一个头文件xxx.h,里面放在这些函数和全局变量的声明。(extern int a;)
ar -r libxxx.a xxx1.o xxx2.o
(2)使用库
写c语言程序usexxx.c,包含头文件xxx.h,程序中可以调用库中的函数,或者访问库中的全局变量。方式一:gcc -c usexxx.c ; gcc usexxx.o libxxx.a
方式二:gcc -c usexxx.c ;gcc usexxx.o -lxxx -L. ,其中-lxxx表示要链接libxxx.a库文件(xxx称为库名),-L表示当前目录(.)下找库文件libxxx.a
方式三:先设置全局环境变量LIBRARY_PATH值为库文件所在的目录,然后gcc -c usexxx.c ; gcc usexxx.o -lxxx
2)动态库(共享库) libxxx.so
(1)写C语言程序(一般不应该有main函数)
gcc -c -fpic xxx1.c xxx2.cgcc -shared -o libxxx.so xxx1.o xxx2.o
(2)使用库
编译时:编写C程序usexxx.c
方式一:gcc -c usexxx.c ;gcc usexxx.o -lxxx -L.
方式二:gcc -c usexxx.c; gcc usexxx.o -lxxx,先设置全局环境变量LIBRARY_PATH
运行时:
方式一:把库文件放到系统标准库目录/usr/lib或者lib目录中就可以运行a.out了。
方式二:设置环境变量LD_LIBRARY_PATH的值为动态库文件所在的目录,然后运行a.out
string.c
void Strtoupper(char *str)
{
while(*str)
{
if(*str>='a' && *str<='z')
{
*str += 'A'-'a';
}
++str;
}
}
void Strtolower(char* str)
{
while(*str)
{
if(*str>='A' && *str <='Z')
{
*str += 'a'-'A';
}
++str;
}
}
str.h
#ifndef STR_H_
#define STR_H_
void Strtoupper(char *str);
void Strtolower(char *str);
void i2str(int ,char *);
extern double gvar;
#endif /* STR_H_ */
i2str.c
#include<string.h>
double gvar=123.45;
void i2str(int d,char *str)
{
int i = 0;
if(d < 0)
{
d = -d;
strcpy(str,"-");
++str;
}
else
{
*str = 0;
}
for(i = 0;i != 0;i ++)
{
str[i] = d % 10 + '0';
d /= 10;
}
if(i == 0)
{
strcpy(str,"0");
}
else
{
for(int j = 0; j < i; j ++)
{
char t = str[j];
str[j] = str[i-1- j];
str[i-1-j] = t;
}
}
}
usestr.c
#include<stdio.h>
#include<string.h>
#include"str.h"
int main()
{
char str[100];
int n;
printf("Please input a string and a int number: ");
scanf("%s%d",str,&n);
puts(str);
Strtoupper(str);
puts(str);
Strtolower(str);
puts(str);
i2str(n,str);
puts(str);
printf("%g,%g\n",gvar,gvar+n);
return 0;
}
Makefile(静态库方法)
usestr:usestr.o string.o i2str.o
ar -r libstr.a string.o i2str.o
gcc usestr.o -lstr -L. -o usestr
usestr.o:usestr.c
gcc -c usestr.c
string.o:string.c
gcc -c string.c
i2str.o:i2str.c
gcc -c i2str.c -std=c99
.PHONEY:clean
clean:
rm -rf usestr usestr.o string.o i2str.o libstr.a
Makefile(动态库)
welcome.c
void welcome(char *str,int n)
{
printf("function welcome!");
printf("Begin!\n");
int i=0;
for(i = 0 ;i < n; i ++)
{
printf("%c",str[i]);
}
printf("End!\n");
}
usewelcome.c
#include<stdio.h>
int main()
{
char wel[10]={"welcome\n"};
welcome(wel,10);
return 0;
}
动态库使用方法
产生可执行文件:写c程序(#include库头文件,可以使用库中的函数和变量),gcc -lxxx -l库文件所在的目录。
c程序文件或者设置环境变量LIBRARY_PATH的值为库文件所在目录从而省略-l选项.
执行可执行文件:先把库文件复制到/lib或者/usr/lib目录下或者设置LD_LIBRARY_PATH为库文件所在的目录,
在执行可执行文件。
~/.bashrc
PATH=$PATH:.
export LIBRARY_PATH=$LIBRARY_PATH:库文件目录
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库文件目录
升级库:把“产生库”的过程重复一遍,如果是动态库,可执行文件会自动使用新库,如果是静态库,还需要重复“
产生可执行文件“的过程,新的可执行文件使用的才是新库。