Linux ·

UNIX/Linux 系统中的环境变量和库文件的使用方法

1 环境变量的概念和使用

1.1 基本概念

环境变量一般是指在操作系统中用来指定操作系统运行环境./应用程序环境的一些变量

path 就是一个环境变量,一般来说应用程序的执行需要带上路径才可以运行,而定义在环境变量path 中的路径,系统会自动识别,因此对应的应用程序只需要程序名称即可运行。

1.2 基本配置

1 Windows 中的配置

我的电脑  -属性- 高级-环境变量-系统变量-path -点编辑,在path 变量后面增加分号,用于分隔路径,在追加新的路径,设置确定,

注意不要删除原来Path 变量原来的变量值,避免出现系统无法启动或者正常运行的情况

2 UNIX/Linux系统中的配置

echo 字符串  表示字符串原样输出,回显

echo $SHELL 表示获取SHELL 的值,进行回显

echo $PATH 获取PATH 的值进行回显打印

export PATH=$PATH:.  解释 export 表示导入,PATH 表示环境变量

$PATH 表示把变量值的取出来。获取环境变量中原来的数值。后面的就是自己加上的路径,:代表分隔,.代表当前的路径

所以这句话的意思就是把当前目录的路径追加到环境变量的值中。

echo $SHELL

但是这行指令只是针对当前终端有效,一次性的。

vi ~/.bashrc 打开文件,在文件最后增加代码,~/代表主目录下,.开头代表隐藏文件,是bash 的配置文件。在这里配置就是永久性的,

export PATH=$PATH:.

export PS1='\W'  这里 '\W'表示只显示一个单词,$结尾。

表示终端的提示符只显示一个单词,使用$结尾

source ~/.bashrc

使得配置文件立即生效

1.3 编程相关的环境变量

C_INCLUDE_PATH/CPATH-C c头文件的附加搜索路径,这里没下划线。

  CPLUS_INCLUDE_PATH-C++  C++头文件的附加搜索路径

LIBRARY_PATH - 链接库文件时候查找路径

LD_LIBRARY_PATH - 运行时查找共享库的路径

1.4 头文件的查找方式

1 #include

表示去系统默认的路径中查找该头文件

whereis +文件 查找文件位置。

2 #include“xxx”

表示优先在当前工作目录下进行查找,这个双引号之内可以加路径,就是../这样,我靠 这也可以,我以前都没见过。

如果保证代码不变进行对C文件的头文件库进行配置

export CPATH=$CPATH:..

这样可以设置头文件的包含路径

3 配置环境变量

export CPATH =$CPATH:..

一次性的,永久的需要加入bash中。这种配置的缺陷是,当有多个工程的时候,环境变量的位置可能引发冲突。

4 使用编译选项 -I

gcc/cc *.c -I 头文件目录

gcc/cc *.c -I ..

最好的方案了,建议使用这种方案,

注意

对于查找头文件的方式12 来说,缺点是一旦头文件的位置发生改变,需要修改源代码,3 的缺陷是多个工程会相互影响,建议使用方案4;

练习

多文件编程结构,实现计算两个int 类型参数的和,通过返回值返回的自定义函数。

2 库文件的概念

1.1 概念

为了调用者使用方便,一般不会直接提供对应的.c或者.o文件,而是根据具体的功能模块,将对应的多个.o 文件打包一个/多个库文件,给调用者提供库文件和头文件即可。

库文件主要分成两种, 静态库和共享库

1 静态库

1 静态库使用时候,直接把代码复制到目标文件中,

优缺点

优点 就是 不需要跳转,效率比较高,脱离静态库。

缺点 目标文件比较大,维护和修改都不方便

2 共享库

共享库使用时候,是把代码的地址复制过来,

优点 目标文件比较小,维护和修改都比较方便

缺点  需要跳转,效率低,不能脱离共享库文件

基本命令

ldd +可执行文件 可以得到他所链接的文件

gcc/cc -static *.c -o b.out 强制要求使用静态库方式生成可执行文件

比较发现静态库方式生成的文件比较大

2.2静态库的生成和使用

1 静态库的生成

a  编写源代码 xxx.c

b  只编译不链接生成目标文件 xxx.o文件

gcc/cc -c add.c

c 生成静态库文件

 ar -r / 插入/ lib库名.a  目标文件

 ar -r libadd.a add.0

注意

静态库的文件名的命名规则, 以lib 开头,以.a 结尾

静态库文件名和库名是不同的概念,库名没前缀和后缀

2 静态库的使用步骤

a 编写测试源代码 xxx.c

b 只编译不链接生成目标文件 xxx.o

gcc/cc -c main.c

c 链接测试文件和静态库文件,连接方式有三种

1 直接链接

cc main.o libadd.a

2 编译选项进行编译链接

gcc/cc main.o -l 库名 -L 库文件所咋的路径

gcc/cc mian.o -l add -L .

  3 掌握第二种就可以,第三种是第二种的变形,配置环境变量LIBRARY_PATH

export LIBRARY_PATH =$LIBRARY_PATH:.

gcc/cc main.o -l add 省略了第二种之中的路径

使用是直接链接静态库文件就可以生成可执行文件,链接时候可以链接多个静态库文件。

cp -r 复制整个文件夹, cp 复制一个文件。

共享库的生成和使用步骤

1 生成步骤

1 编写源码

2 只编译不连接生成目标文件

gcc/cc -c -fpic //小模式代码少)  add.c

3 生成共享库文件

gcc /cc -shared 目标文件 -o lib库名.so

gcc/cc -shared /共享/ add.o -o libadd.so

2 共享库的使用

a 编写测试源代码 xxx.c

b 只编译不链接生成目标文件 xxx.o

gcc/cc -c main.c

c 链接测试文件和共享库文件,连接方式有三种

1 直接链接

cc main.o libadd.so

2 编译选项进行编译链接

gcc/cc main.o -l 库名 -L 库文件所咋的路径

gcc/cc mian.o -l add -L .

  3 掌握第二种就可以,第三种是第二种的变形,配置环境变量LIBRARY_PATH

export LIBRARY_PATH =$LIBRARY_PATH:.

gcc/cc main.o -l add 省略了第二种之中的路径

ldd 查看共享库的信息

直接生成运行的时候会发生错误,找不到共享库文件。需要配置运行时的共享库环境变量配置。

export LD_LIBRARY_PATH =$LD_LABRARY_PATH:.

注意事项,共享库的实现需要要求配置环境变量,LD_LIBRARY_PATH 的值,主要解决运行时找不到共享库的问题。

记住步骤,先用别的文件生成库文件,而后生成源码的.o 文件,而后进行链接  链接主要是第二种方法,第一种是直接链接比较简单,第三种是第二种的改编, gcc/cc main.o -l add -L .最后的是文件的路径,我的虚拟机出了问题我不能自己直接链接了

共享库的动态加载

1 dlopen 函数

动态加载共享库功能函数的接口函数,

 #include

void *dlopen (const char * filename,int flag);

dlopen 第一个参数是共享库文件的函数名,第二个是int型标志位,返回值是void * 是viod 类型的函数指针。就是句柄,暂时理解为首地址。

函数功能是打开和加载库文件。

如果调用失败,返回一个空地址NULL;成功就返回句柄。

传递第二个实参,必须包括两个参数  RTLD_LAZY和  RTLD_NOW。第一个表示延迟加载,第二个表示立即加载。

2 dlerror char *dlerror (void);

返回的就是dlopen dlclose dlsym 三个函数的最近发生的一个错误信息。返回NULL则表示没有错误发生。

3 dlsym 函数

void *dlsym(void * handle,const char *symbol);

第一个参数要的是一个句柄信息,也就是dlopen 这个函数的返回值

第二个参数 字符串形式的符号,表示函数名

返回值:成功返回的是函数在内存中的地址,失败返回NULL,

函数功能:主要用于根据句柄和函数名获取在内存中的地址。

4 dlclose 函数,int dlclose (void *handle );

参数是dlopen 的返回值,用来关闭dlopen 的返回值所指定的共享库,就是回收动态库在加载中所占有的空间。

5

返回0 表示成功,返回非零表示失败。当共享库不在被函数使用的时候,不在被任何程序使用时候,则收回共享库所占有的空间。

注意:编译链接时候需要增加选项:-ldl

共享库的动态加载。dynamic

编程实现打印空心的菱形和实心的菱形。对打印函数所在的文件分别打包成静态库文件和共享库文件进行调用。

参与评论