LinuxDev 板


LINE

Library可分成三种,static、shared与dynamically loaded。 1. Static libraries Static 程式库用於静态连结,简单讲是把一堆object档用ar(archiver) 包装集合起来,档名以 `.a' 结尾。优点是执行效能通常会比後两者快, 而且因为是静态连结,所以不易发生执行时找不到library或版本错置而 无法执行的问题。缺点则是档案较大,维护度较低;例如library如果发 现bug需要更新,那麽就必须重新连结执行档。 1.1 编译 编译方式很简单,先例用 `-c' 编出 object 档,再用 ar 包起来即可。 ____ hello.c ____ #include <stdio.h> void hello(){ printf("Hello "); } ____ world.c ____ #include <stdio.h> void world(){ printf("world."); } ____ mylib.h ____ void hello(); void world(); $ gcc -c hello.c world.c /* 编出 hello.o 与 world.o */ $ ar rcs libmylib.a hello.o world.o /* 包成 limylib.a */ 这样就可以建出一个档名为 libmylib.a 的档。输出的档名其实没有硬性规定, 但如果想要配合 gcc 的 '-l' 参数来连结,一定要以 `lib' 开头,中间是你要 的library名称,然後紧接着 `.a' 结尾。 1.2 使用 ____ main.c ____ #include "mylib.h" int main() { hello(); world(); } 使用上就像与一般的 object 档连结没有差别。 $ gcc main.c libmylib.a 也可以配合 gcc 的 `-l' 参数使用 $ gcc main.c -L. -lmylib `-Ldir' 参数用来指定要搜寻程式库的目录,`.' 表示搜寻现在所在的目录。 通常预设会搜 /usr/lib 或 /lib 等目录。 `-llibrary' 参数用来指定要连结的程式库 ,'mylib' 表示要与mylib进行连结 ,他会搜寻library名称前加`lib'後接`.a'的档案来连结。 $ ./a.out Hello world. 2. Shared libraries Shared library 会在程式执行起始时才被自动载入。因为程式库与执行档 是分离的,所以维护弹性较好。有两点要注意,shared library是在程式起始 时就要被载入,而不是执行中用到才载入,而且在连结阶段需要有该程式库 才能进行连结。 首先有一些名词要弄懂,soname、real name与linker name。 soname 用来表示是一个特定 library 的名称,像是 libmylib.so.1 。 前面以 `lib' 开头,接着是该 library 的名称,然後是 `.so' ,接着 是版号,用来表名他的介面;如果介面改变时,就会增加版号来维护相容度。 real name 是实际放有library程式的档案名称,後面会再加上 minor 版号与 release 版号,像是 libmylib.so.1.0.0 。 一般来说,版号的改变规则是(印象中在 APress-Difinitive Guide to GCC中有 提到,但目前手边没这本书),最尾码的release版号用於程式内容的修正, 介面完全没有改变。中间的minor用於有新增加介面,但相旧介面没改变,所以 与旧版本相容。最前面的version版号用於原介面有移除或改变,与旧版不相容 时。 linker name是用於连结时的名称,是不含版号的 soname ,如: libmylib.so。 通常 linker name与 real name是用 ln 指到对应的 real name ,用来提供 弹性与维护性。 2.1 编译 shared library的制作过程较复杂。 $ gcc -c -fPIC hello.c world.c 编译时要加上 -fPIC 用来产生 position-independent code。也可以用 -fpic 参数。 (不太清楚差异,只知道 -fPIC 较通用於不同平台,但产生的code较大 ,而且编译速度较慢)。 $ gcc -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1.0.0 \ hello.o world.o -shared 表示要编译成 shared library -Wl 用於参递参数给linker,因此-soname与libmylib.so.1会被传给linker处理。 -soname用来指名 soname 为 limylib.so.1 library会被输出成libmylib.so.1.0.0 (也就是real name) 若不指定 soname 的话,在编译结连後的执行档会以连时的library档名为 soname,并载入他。否则是载入soname指定的library档案。 可以利用 objdump 来看 library 的 soname。 $ objdump -p libmylib.so | grep SONAME SONAME libmylib.so.1 若不指名-soname参数的话,则library不会有这个栏位资料。 在编译後再用 ln 来建立 soname 与 linker name 两个档案。 $ ln -s libmylib.so.1.0.0 libmylib.so $ ln -s libmylib.so.1.0.0 libmylib.so.1 2.2 使用 与使用 static library 同。 $ gcc main.c libmylib.so 以上直接指定与 libmylib.so 连结。 或用 $ gcc main.c -L. -lmylib linker会搜寻 libmylib.so 来进行连结。 如果目录下同时有static与shared library的话,会以shared为主。 使用 -static 参数可以避免使用shared连结。 $ gcc main.c -static -L. -lmylib 此时可以用 ldd 看编译出的执行档与shared程式库的相依性 $ldd a.out linux-gate.so.1 => (0xffffe000) libmylib.so.1 => not found libc.so.6 => /lib/libc.so.6 (0xb7dd6000) /lib/ld-linux.so.2 (0xb7f07000) 输出结果显示出该执行档需要 libmylib.so.1 这个shared library。 会显示 not found 因为没指定该library所在的目录,所找不到该library。 因为编译时有指定-soname参数为 libmylib.so.1 的关系,所以该执行档会 载入libmylib.so.1。否则以libmylib.so连结,执行档则会变成要求载入 libmylib.so $ ./a.out ./a.out: error while loading shared libraries: libmylib.so.1: cannot open shared object file: No such file or directory 因为找不到 libmylib.so.1 所以无法执行程式。 有几个方式可以处理。 a. 把 libmylib.so.1 安装到系统的library目录,如/usr/lib下 b. 设定 /etc/ld.so.conf ,加入一个新的library搜寻目录,并执行ldconfig 更新快取 c. 设定 LD_LIBRARY_PATH 环境变数来搜寻library 这个例子是加入目前的目录来搜寻要载作的library $ LD_LIBRARY_PATH=. ./a.out Hello world. 3. Dynamically loaded libraries Dynamicaaly loaded libraries 才是像 windows 所用的 DLL ,在使用到 时才载入,编译连结时不需要相关的library。动态载入库常被用於像plug-ins 的应用。 3.1 使用方式 动态载入是透过一套 dl function来处理。 #include <dlfcn.h> void *dlopen(const char *filename, int flag); 开启载入 filename 指定的 library。 void *dlsym(void *handle, const char *symbol); 取得 symbol 指定的symbol name在library被载入的记忆体位址。 int dlclose(void *handle); 关闭dlopen开启的handle。 char *dlerror(void); 传回最近所发生的错误讯息。 ____ dltest.c ____ #include <stdio.h> #include <stdlib.h> #include <dlfcn.h> int main() { void *handle; void (*f)(); char *error; /* 开启之前所撰写的 libmylib.so 程式库 */ handle = dlopen("./libmylib.so", RTLD_LAZY); if( !handle ) { fputs( dlerror(), stderr); exit(1); } /* 取得 hello function 的 address */ f = dlsym(handle, "hello"); if(( error=dlerror())!=NULL) { fputs(error, stderr); exit(1); } /* 呼叫该 function */ f(); dlclose(handle); } 编译时要加上 -ldl 参数来与 dl library 连结 $ gcc dltest.c -ldl 结果会印出 Hello 字串 $ ./a.out Hello 关於dl的详细内容请参阅 man dlopen -- 参考资料: Creating a shared and static library with the gnu compiler [gcc] http://www.adp-gmbh.ch/cpp/gcc/create_lib.html Program Library HOWTO http://tldp.org/HOWTO/Program-Library-HOWTO/index.html APress - Definitive Guide to GCC --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.139.148.148
1F:推 TroyLee:推这篇... 11/05 04:38
2F:推 WalkingIce:太详细了!推! 11/05 05:11
3F:→ qrtt1:感谢分享:D 11/05 08:24
4F:→ letoh:win dll 也有分 dynamic linking/loading 11/05 11:29
5F:推 maxplanck:大推 说明的很详细 11/05 21:31
6F:推 xacid:好棒,一看就懂 11/05 23:23
7F:推 hakka:大推 写的清楚明白 11/06 11:25
8F:推 kewang:大推 11/28 16:58
9F:推 H45:push 07/02 09:21
10F:推 previewslave:推阿~推阿~推阿~~阿勒固~阿勒固~阿勒固固固~! 07/05 12:54
11F:推 tortoise:推好文 05/16 09:40
12F:推 milochen:感谢分享 06/08 10:05







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Gossiping站内搜寻

TOP