Windows与Linux动态链接库技术的对比
来源:互联网 发布:洗车软件app 编辑:程序博客网 时间:2024/05/19 20:21
Windows与Linux动态链接库区别概述
Windows与Linux对动态链接库的实现虽然思想相同,但是使用方式却有些不同。下表总结了这一区别。
gcc main.c -Wl,-Bstatic-lcalc -Wl,-Bdynamic -lm
gcc main.c ./libcalc.a -lm
动态库以libname.so方式命名。
若不遵循这两个规则,那么gcc -l选项便无法找到指定的库。
动态库以name.dll方式命名。
Linux链接库的使用
测试程序如下:
/*calc.c*/int val = 10;static int inner_val = 20;int Add(int a,int b){ return a + b;}
/*test.c*/#include <stdio.h>extern int val;extern int Add(int a,int b);int main(){ printf("val:%d\n",val); printf("4 + 4:%d\n",Add(4,4)); return 0;}
静态链接库的使用
生成可重定向文件
gcc创建静态链接库的方式如下,这并不局限于Linux,如在Cygwin下也是如此。
$gcc -c calc.c -o calc.o
在C语言当中被static修饰的变量或函数是私有的,因为在calc.c当中val与Add符号未被static修饰,所以可以在任意的其它模块当中使用val变量或调用Add函数,这意味着val变量是全局的,它的值可以被任何链接到它的一个模块更改。我们可以通过readelf查看calc.o的符号信息,从中可以看出inner_val被LOCAL修饰,而val和Add被GLOBAL修饰。
$ readelf -s calc.oSymbol table '.symtab' contains 11 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 FILE LOCAL DEFAULT ABS calc.c 2: 00000000 0 SECTION LOCAL DEFAULT 1 3: 00000000 0 SECTION LOCAL DEFAULT 2 4: 00000000 0 SECTION LOCAL DEFAULT 3 5: 00000004 4 OBJECT <span style="color:#ff0000;">LOCAL </span>DEFAULT 2 inner_val 6: 00000000 0 SECTION LOCAL DEFAULT 5 7: 00000000 0 SECTION LOCAL DEFAULT 6 8: 00000000 0 SECTION LOCAL DEFAULT 4 9: 00000000 4 OBJECT <span style="color:#ff0000;">GLOBAL </span>DEFAULT 2 val 10: 00000000 13 FUNC <span style="color:#ff0000;">GLOBAL </span>DEFAULT 1 Add
创建归档文件
$ar rcs libcalc.a calc.o静态链接库将可重定向目标文件(.o文件)以特定的格式压缩在一起,从而解决.o文件管理混乱的问题,下面的命令可以查看.a文件当中包含了哪些.o文件。
$ ar -t /usr/lib/i386-linux-gnu/libc.ainit-first.olibc-start.osysdep.oversion.ocheck_fds.olibc-tls.oelf-init.o...也可以查看.a文件当中每个.o文件的符号信息
$ nm /usr/lib/i386-linux-gnu/libc.a | head -200init-first.o: U abort U __ctype_init U _dl_fpu_control U _dl_non_dynamic_init00000090 T _dl_start w _dl_starting_up U __environ U __fpu_control U __init_misc00000004 C __libc_argc00000004 C __libc_argv00000000 T __libc_init_first U __libc_init_secure00000000 D __libc_multiple_libcs U __setfpucwlibc-start.o: U __assert_fail U __cxa_atexit U _dl_aux_init U _dl_discover_osversion U _dl_osversion...
使用静态链接库
使用方式一,显式链接
gcc test.c ./libcalc.a -o test使用方式二,隐式链接
gcc test.c -L. -static -lcalc -o test使用显式链接的时候我们不用关心静态链接库的名称问题,但是对于隐式链接必须遵从gcc对链接库的名称要求:静态库:libname.a,动态库libname.so。
隐式链接静态库的时候必须指定-static选项,若没有指定-static选项,gcc在链接的时候使用动态链接库的算法进行链接,这虽然不会出报错,但是在程序执行的时候实际其会要求加载libcalc.so,由于我们没有libcalc.so,所以程序无法执行。
另外,我们可以更改一下程序以验证上面提到的使用static修饰的变量不可被外部模块链接的说法。这里不做示例。
在链接静态库的时候还有一个陷阱需要注意。由于gcc链接的时候内部算法约束,参数的传递顺序对链接的成功起至关重要。上面的例子当中使用如下方式链接会报错。
gcc ./libcalc.a test.c -o test
动态链接库的使用
创建动态链接库
众所周知,动态链接库的一个主要目的是允许多个正在运行的进程共享存储器中相同的库代码,因而解决宝贵的存储器资源。gcc创建一个动态链接库十分简单,并没有像VC一样单独导出一个可链接的符号文件(见Windows下动态链接库的使用),我们可以在main.c代码当中使用任何非static修饰的变量或函数。
gcc -shared calc.c -o libcalc.so另外,我们可以查看生成的动态库当中可链接的动态符号表,当我们的程序由于某个符号找不到无法链接的时候可以通过这个手段进行确认。
$ readelf -s libcalc.soSymbol table '<span style="color:#ff0000;">.dynsym</span>' contains 13 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab 2: 00000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.1.3 (2) 3: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 4: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 5: 00000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable 6: 00002020 0 NOTYPE GLOBAL DEFAULT 21 _edata 7: 00002018 4 OBJECT GLOBAL DEFAULT 21 val 8: 00002024 0 NOTYPE GLOBAL DEFAULT 22 _end 9: 00002020 0 NOTYPE GLOBAL DEFAULT 22 __bss_start 10: 0000050b 13 FUNC GLOBAL DEFAULT 11 Add 11: 00000380 0 FUNC GLOBAL DEFAULT 9 _init 12: 00000518 0 FUNC GLOBAL DEFAULT 12 _finiSymbol table '<span style="color:#ff0000;">.symtab</span>' contains 56 entries: Num: Value Size Type Bind Vis Ndx Name ... 38: 00000000 0 FILE LOCAL DEFAULT ABS 39: 000003e0 4 FUNC LOCAL DEFAULT 11 __x86.get_pc_thunk.bx 40: 00002014 0 OBJECT LOCAL DEFAULT 21 __dso_handle 41: 00001f0c 0 OBJECT LOCAL DEFAULT 18 _DYNAMIC 42: 00002020 0 OBJECT LOCAL DEFAULT 21 __TMC_END__ 43: 00002000 0 OBJECT LOCAL DEFAULT 20 _GLOBAL_OFFSET_TABLE_ 44: 00000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab 45: 00002020 0 NOTYPE GLOBAL DEFAULT 21 _edata 46: 00000518 0 FUNC GLOBAL DEFAULT 12 _fini 47: 00000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@@GLIBC_2.1 48: 00002018 4 OBJECT GLOBAL DEFAULT 21 val 49: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 50: 00002024 0 NOTYPE GLOBAL DEFAULT 22 _end 51: 00002020 0 NOTYPE GLOBAL DEFAULT 22 __bss_start 52: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 53: 00000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable 54: 0000050b 13 FUNC GLOBAL DEFAULT 11 Add 55: 00000380 0 FUNC GLOBAL DEFAULT 9 _init上面打印的信息当中.dynsym段包含了其它应用程序可以使用的符号信息,.symtab包含了该动态链接库当中所有可用的符号信息,其是.dynsym的超集。
使用动态链接库
第一种方式,显式链接
gcc test.c ./libcalc.so
第二种方式,隐式链接
gcc test.c -L. -lcalc -o test使用显式链接十分方便,但是你需要明确知道动态链接库的位置,另外下面的链接方法是错误的 。
$ gcc test.c libcalc.so -o test$ ./test./test: error while loading shared libraries: libcalc.so: cannot open shared object file: No such file or directory$
- Windows与Linux动态链接库技术的对比
- Windows与Linux动态链接库技术的对比
- linux&Windows动态链接库技术实现和设计程序常用的技术
- Linux的动态链接库技术
- LINUX-动态链接与静态链接对比(动态库和静态库)
- Qt: Window, Linux动态链接库的分析对比
- Qt: Window, Linux动态链接库的分析对比
- Window, Linux动态链接库的分析对比
- Qt: Window, Linux动态链接库的分析对比
- 转]Window, Linux动态链接库的分析对比
- Linux与windows的对比
- 动态库技术(windows与linux动态库)
- 对比Windows和Linux两系统的动态库
- 对比Windows和Linux两系统的动态库
- 对比Windows和Linux两系统的动态库
- 动态链接与静态链接对比
- Windows的动态链接库
- windows和linux注册动态链接库的方法
- 黑马程序员——java基础---交通灯管理系统
- z-index的属性
- Linux文件系统详解(文件系统层次、分类、存储结构、存储介质、文件节点inode)
- 客户端和服务器端路径问题及资源的获取
- unity游戏移植到WindowsPhone8平台上的一些经验
- Windows与Linux动态链接库技术的对比
- VS2013+QT5.4.1环境配置和注意事项
- Codeforces Round #157 (Div. 2)
- set,map,list集合的交集差集存放相同值反转分割等-代码优雅之道Guava(三)
- C语言编程——次数排序--结构体数组及冒泡排序法
- 有关上传下载的路径问题
- 云盘秒传原理的探讨——哈希查找与数据去重
- java中的异常
- 《Scala编程》学习笔记(17~18章)