gcc动态链接库的问题,100分相赠,多谢

x-teamer团队 2009-11-25 09:53:23
在windows系统下, 动态链接库称为DLL, 有很多方式用这个东东:

.h + .lib + .dll =》 方式一

.lib + dll =》 方式二

dll =》 方式三


据我所知,DLL若是要被.exe文件使用,是不需要参与编译的, 只需要把.h, Lib包含进去编译即可搞定.







而在Linux系统下, 动态链接库称为: share object, .so文件

这样的so文件确始终参与了编译, 并且有点奇怪, so文件参与了编译生成可执行程序,

此时, 将一个新的.so文件替换原来参与编译的.so文件(保证用到的接口不变), 依然可以调用~

我的理解是: 参与编译的库, 必然是静态的. gcc通过so保证静态编译,又能做到动态连接???

灰常不理解~ gcc的动态链接原理.


高深的道理,浅显的诠释,才是高手....

期待这样的高手
...全文
400 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
iamliadai 2009-11-26
  • 打赏
  • 举报
回复
ELF 文件中包含足够的符号信息供链接。.a .so 都是elf格式。 gcc 也可以只用参数指定符号库链接,而不用调用实际的so 像kernel有个map表一样。 linux下面有个工具可以导出elf的符号表。可以用这个符号表用作gcc的参数 去链接
x-teamer团队 2009-11-26
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 steedhorse 的回复:]
引用 10 楼 jackyjkchen 的回复:
为了简化操作,使用lib的隐式链接要容易得多也可靠得多,否则一堆loadlibrary+函数指针搞死人的,试想一下,若没有Windows SDK提供(h+lib),调用API的难度将会大多少!

akirya说的不是LoadLibrary + GetProcAddress那种方式。他的意思是说,dll本身也带有所需的各种符号,为何连接器要用lib而不像Linux里那样直接基于dll。
[/Quote]

非常想知道这个问题的答案, 按理说,只要dll存在符号信息(像 .so 文件一样), 这样就更加省略了生成.lib的过程.
x-teamer团队 2009-11-26
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 jackyjkchen 的回复:]
始终参与编译?这是何解,应该是只参与了链接吧。
[/Quote]

sorry, 确实说错
shiweifu 2009-11-26
  • 打赏
  • 举报
回复
不止是LINUX平台下,在WINDOWS下用MINGW编译也只需要一个.H和动态链接库文件
x-teamer团队 2009-11-26
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 steedhorse 的回复:]
Linux下面的共享库是ELF格式的,跟Windows下PE格式的dll不一样,包括用法上也不一样。
Linux下面的.so共享库除了在运行时被加载运行之外,本身还包括连接所需的信息,因此它还能直接参与连接过程,而不需要.a的存在。这一点上,倒有点很像Java的class文件——连接、运行的都是同样一个文件,而没有Windows下的lib/dll之分。
Linux上面的.a只对应Windows下的代码lib,而不是符号lib。
[/Quote]

这个回复非常精彩, 多谢!
guzhijie1981 2009-11-26
  • 打赏
  • 举报
回复
lz我顶下;最近我也在搞这个东西;快郁闷死鸟
x-teamer团队 2009-11-26
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 do_fork 的回复:]
没有so文件,ld如何知道xx符号(可能是函数,可能是变量)的地址?
[/Quote]

您是指SO文件里面, 包含二进制代码和符号信息,

也就是说: linux下的So文件,相当于windows下的DLL(二进制文件) + Lib(符号文件),

可以这样理解吗? 谢谢!
hemiya 2009-11-25
  • 打赏
  • 举报
回复
linux下的编程没接触过.但是也接触过linux并且也在linux下编译过一些开源的代码.
so不可能每次都加入编译的,那样做会慢死,so文件本身可能在文件的某处保存了so文件内部所有导出函数和类的入口地址(不一定对).

c++builder中的package和so的表面看起来差不多.如果其中的一个bpl重新编译了,但接口不变,只要你的exe程序本身的bpl的连接方式要是runtime方式连接的,exe本身就不必重新编译.

可能我自己比较懒,不太喜欢windows本身的dll方式,使用起来比较繁琐.我更喜欢c++builder中的bpl比dll方便多了.
lvyinghong 2009-11-25
  • 打赏
  • 举报
回复
do_fork 说的没错,记得用看过从dll 制作 lib的。
可能lib 文件格式微软的链接工具用起来更舒服吧
do_fork 2009-11-25
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 jackyjkchen 的回复:]
引用 11 楼 steedhorse 的回复:
引用 10 楼 jackyjkchen 的回复:
为了简化操作,使用lib的隐式链接要容易得多也可靠得多,否则一堆loadlibrary+函数指针搞死人的,试想一下,若没有Windows SDK提供(h+lib),调用API的难度将会大多少!

akirya说的不是LoadLibrary + GetProcAddress那种方式。他的意思是说,dll本身也带有所需的各种符号,为何连接器要用lib而不像Linux里那样直接基于dll。

应该是微软的商业策略,dll只提供二进制代码,要想在编程中调用,得购买开发工具,不过后来微软也免费公开了SDK。

另一方面,就是Windows的定位了——不向linux那样是针对开发者或专业用户的,若在dll里加上符号信息,效率和体积代价都会增加,也不利于二进制文件的保护,普通的用户根本用不到dll的符号信息是不是。
[/Quote]

dll里面有符号信息的,用dependency walker查看dll的时候可以看到那些信息,
如果dll中没有符号信息,dumpbin就无法从dll导出lib了
superbtl 2009-11-25
  • 打赏
  • 举报
回复
我的理解
linux上 .so的.h文件参与编译,但是.so也要存在,相当于.h对.so里的函数的引用,但是.so不参与链接,所以你的执行文件要有.so文件伴随着才可以使用,最后交付的是exe+.so。
.a是静态的,编译链接都要有,直接连接到执行文件里,链接后不需要.a的,但是执行文件也相应大了,因为有静态库的东西进去了,最后只要交付exe就可以了。

其实VC上的原理一样。
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 jackyjkchen 的回复:]
引用 11 楼 steedhorse 的回复:
引用 10 楼 jackyjkchen 的回复:
为了简化操作,使用lib的隐式链接要容易得多也可靠得多,否则一堆loadlibrary+函数指针搞死人的,试想一下,若没有Windows SDK提供(h+lib),调用API的难度将会大多少!

akirya说的不是LoadLibrary + GetProcAddress那种方式。他的意思是说,dll本身也带有所需的各种符号,为何连接器要用lib而不像Linux里那样直接基于dll。

应该是微软的商业策略,dll只提供二进制代码,要想在编程中调用,得购买开发工具,不过后来微软也免费公开了SDK。

另一方面,就是Windows的定位了——不向linux那样是针对开发者或专业用户的,若在dll里加上符号信息,效率和体积代价都会增加,也不利于二进制文件的保护,普通的用户根本用不到dll的符号信息是不是。
[/Quote]
导出表的信息已经足够了啊
晨星 2009-11-25
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 akirya 的回复:]
问题重点不在于这里,Delphi只需要在代码中声明,然后指定dll,就可以直接调用了,不需要loadlibrary。
这点说明,不需要lib中的信息就能连接成功。

dll的导出表的信息足够链接了,只是不知道为啥还非得需要lib才能链接。
[/Quote]
不清楚如果Delphi程序使用VC编写的dll,是否也能做到这样。如果也能做到,那就只能说明VC玩花样或者另有其它的非技术原因了,呵呵。
jackyjkchen 2009-11-25
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 steedhorse 的回复:]
引用 10 楼 jackyjkchen 的回复:
为了简化操作,使用lib的隐式链接要容易得多也可靠得多,否则一堆loadlibrary+函数指针搞死人的,试想一下,若没有Windows SDK提供(h+lib),调用API的难度将会大多少!

akirya说的不是LoadLibrary + GetProcAddress那种方式。他的意思是说,dll本身也带有所需的各种符号,为何连接器要用lib而不像Linux里那样直接基于dll。
[/Quote]
应该是微软的商业策略,dll只提供二进制代码,要想在编程中调用,得购买开发工具,不过后来微软也免费公开了SDK。

另一方面,就是Windows的定位了——不向linux那样是针对开发者或专业用户的,若在dll里加上符号信息,效率和体积代价都会增加,也不利于二进制文件的保护,普通的用户根本用不到dll的符号信息是不是。
晨星 2009-11-25
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 zhengaw 的回复:]
编译的时候貌似只要头文件就可以的.
[/Quote]
对,WIN下面,编译用.h,连接用.lib,运行用.dll。各司其职,呵呵。
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 jackyjkchen 的回复:]
引用 6 楼 akirya 的回复:
按理说,dll也一样包括了连接所需要的信息,不需要lib就能连接成功。只是不清楚dll对应lib存在的原因。

为了简化操作,使用lib的隐式链接要容易得多也可靠得多,否则一堆loadlibrary+函数指针搞死人的,试想一下,若没有Windows SDK提供(h+lib),调用API的难度将会大多少!
[/Quote]
问题重点不在于这里,Delphi只需要在代码中声明,然后指定dll,就可以直接调用了,不需要loadlibrary。
这点说明,不需要lib中的信息就能连接成功。

dll的导出表的信息足够链接了,只是不知道为啥还非得需要lib才能链接。
qingyaoli 2009-11-25
  • 打赏
  • 举报
回复
编译的时候貌似只要头文件就可以的.
晨星 2009-11-25
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 jackyjkchen 的回复:]
为了简化操作,使用lib的隐式链接要容易得多也可靠得多,否则一堆loadlibrary+函数指针搞死人的,试想一下,若没有Windows SDK提供(h+lib),调用API的难度将会大多少!
[/Quote]
akirya说的不是LoadLibrary + GetProcAddress那种方式。他的意思是说,dll本身也带有所需的各种符号,为何连接器要用lib而不像Linux里那样直接基于dll。
jackyjkchen 2009-11-25
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 akirya 的回复:]
按理说,dll也一样包括了连接所需要的信息,不需要lib就能连接成功。只是不清楚dll对应lib存在的原因。
[/Quote]
为了简化操作,使用lib的隐式链接要容易得多也可靠得多,否则一堆loadlibrary+函数指针搞死人的,试想一下,若没有Windows SDK提供(h+lib),调用API的难度将会大多少!
晨星 2009-11-25
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 akirya 的回复:]
按理说,dll也一样包括了连接所需要的信息,不需要lib就能连接成功。只是不清楚dll对应lib存在的原因。
[/Quote]
哦,这个原来倒不是很清楚。一直以为Win下的连接过程是离不了lib的。
多谢指点。
加载更多回复(8)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧