G++,静态库,动态库

G++(Linux)

-I(大写i),到指定目录搜索头文件
-L,到指定目录搜索库文件
-l(小写L),到前面指定的目录下添加库文件进行链接
-o,为生成文件重命名
   g++ -E xxx.cpp
   不加-o 生成xxx.i
   加-o xxx123 生成xxx123
-E,将源代码 .c/.cpp文件进行预编译
   将所有#define删除
   并且展开所有的宏定义处理所有的条件预编译指令,如#if #ifdef #undef #ifndef #endif #elif处理#include
   将包含的文件插入到此处,这是一个递归的过程
   删除所有注释 // /* */添加行号和文件名标识,以便于编译时产生的错误警告能显示行号
   保留#pragma编译器指令
   g++ -E xxx.cpp 生成xxx.i
-S,将预处理完的.i文件进行一系列的词法分析、语法分析、语义分析及优化后生成响应的汇编代码文件
   g++ -S xxx.cpp/xxx.i 生成xxx.s
-c,生成目标文件 以xxx.o结尾,可以用于生成库文件
   g++ -c xxx.cpp/xxx.s 生成xxx.o

静态库

在g++ -c命令创建完.o结尾的目标文件后,可以通过ar命令打包成静态库
实际上ar命令是用于创建备存文件的,将一些文件打包成一个文件,类似于压缩文件,但不完全等于压缩文件
实际上在调用g++ -l(小写L)指令的时候将备存文件中的.o文件提取出来进行链接操作
但是在链接中需要用到-L来指示库文件所在目录,用-l(小写L)来指定库文件
而-l(小写L)时会补充xxx前后的lib与.a,所以在使用ar命令来打包静态库的时候需要直接命名为libxxx.a
在实际上以下两种链接方法完全等效

$ g++ main.cpp -L./lib -lmath

$ g++ main.cpp math.o

一般对.o结尾的目标文件生成静态库的时候,使用以下参数
ar rcs [备存文件] [成员文件]
(静态库文件名) (目标文件名)
例 ar rcs libmath.a math.o

更多ar命令,请看以下
Linux ar命令

动态库

动态库编译方式如同静态库一样,先要编译出目标文件.o,然后组成.so库—— g++ -c math.cpp -o math.o
但是这次编译需要用到-fPIC指令来编译,在g++ -fPIC -c math.cpp -o math.o
获得了目标文件.o后,需要用指令-shared声明将.o文件链接成.so库,g++ -shared -o libmath.so math.o
实际上生成.so库可以合成一个指令,g++ -fPIC -shared math.cpp -o libmath.so
编译main.cpp时,需要和链接静态库一样,要用到-L与-l(小写L),但是要添加-ldl,g++ math.cpp -L ./so/ -lmath -ldl
关于载入动态库的规则:
在Linux中,系统会按照一定方式搜索动态库文件

  • (仅限ELF)如果调用程序的可执行文件包含 DT_RPATH 标记,并且不包含 DT_RUNPATH 标记,则会搜索 DT_RPATH 标记中列出的目录。
  • 如果在程序启动时,环境变量 LD_LIBRARY_PATH 被定义为包含以冒号分隔的目录列表,则会搜索这些目录。 (作为安全措施,set-user-ID 和 set-group-ID程序将忽略此变量。)
  • (仅限ELF)如果调用程序的可执行文件包含 DT_RUNPATH 标记,则搜索该标记中列出的目录。
  • 检查缓存文件/etc/ld.so.cache(由ldconfig(8)维护)以查看它是否包含filename的条目。
  • 搜索目录 /lib和 /usr/lib(按此顺序)。
    例如创建环境变量 LD_LIBRARY_PATH ,在中间加入动态库的目录,export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./so

在执行调用动态库时,需要对以上规则内的目录进行添加对应动态库,也可以用ldd命令查看可执行文件中调用的动态库是否存在对应的文件,ldd a.out

如何执行动态库中的程序?
一、隐式执行
二、显示执行

一、隐式执行

库文件中的可执行函数都声明为静态(static),int main()中直接调用该静态函数,道理懂得都懂。

二、显示执行

使用<dlfcn.h>函数库中各种库函数,加载动态库,执行动态库中程序etc.
介绍几个常用动态库函数
1.dlopen
  void* dlopen(const char* filename,int mode)
  filename 为动态库名,mode为载入动态库的方式模式。

  mode:
  1、解析方式
  RTLD_LAZY:在dlopen返回前,对于动态库中的未定义的符号不执行解析(只对函数引用有效,对于变量引用总是立即解析)。
  RTLD_NOW: 需要在dlopen返回前,解析出所有未定义符号,如果解析不出来,在dlopen会返回NULL,错误为:: undefined symbol: xxxx.......
  2、作用范围,可与解析方式通过“|”组合使用。
  RTLD_GLOBAL:动态库中定义的符号可被其后打开的其它库解析。
  RTLD_LOCAL: 与RTLD_GLOBAL作用相反,动态库中定义的符号不能被其后打开的其它库重定位。如果没有指明是RTLD_GLOBAL还是RTLD_LOCAL,则缺省为RTLD_LOCAL。
  3、作用方式
  RTLD_NODELETE: 在dlclose()期间不卸载库,并且在以后使用dlopen()重新加载库时不初始化库中的静态变量。这个flag不是POSIX-2001标准。
  RTLD_NOLOAD: 不加载库。可用于测试库是否已加载(dlopen()返回NULL说明未加载,否则说明已加载),也可用于改变已加载库的flag,如:先前加载库的flag为RTLD_LOCAL,用dlopen(RTLD_NOLOAD|RTLD_GLOBAL)后flag将变成RTLD_GLOBAL。这个flag不是POSIX-2001标准。
  RTLD_DEEPBIND:在搜索全局符号前先搜索库内的符号,避免同名符号的冲突。这个flag不是POSIX-2001标准。

  dlopen执行后返回一个handle

2.dlsym
  void* dlsym(void* handle,const char* symbol)
  执行完后返回handle中的对应symbol符号的地址
  其中handle就是dlopen执行完后的handle,symbol就是要求获取的函数或全局变量的名称
  关于symbol,其中有说法的是符号名
  因为在c++中为了保证多态性,函数都能进行重载,所以在c++中的符号名不是完全按照函数名来命名,会按照不同编译器的方式进行改编
  而c中不需要保证多态性,所以符号名都为函数名。
  所以在需要进行c方式编译的代码段,用 extern "C" 来声明这一段代码用C语言来编译,使用dlsym时,便可以通过函数名来调用库中的函数

3.dlclose
  int dlclose (void *handle)
  传入handle,卸载handle所指的动态库内存区域

4.dlerror
  char *dlerror(void)
  返回错误信息

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容