在编译时链接到共享对象

问题描述:

在Windows中,许多.dll都带有一个静态的.lib副本。我的理解是,.lib对手基本上包含LoadProcAddress调用,因此程序员不必自己做。本质上,节省时间。当我切换到Linux时,我认为情况是一样的,以.so和.lib替换.d与.a替换为.a,但我遇到了一种情况,显示我这是错误的,我无法弄清楚什么正在进行中:在编译时链接到共享对象

我正在使用作为.a/.so对出现的库。我正在连接.a,但是当我在生成的二进制文件上执行ldd时,它不包含对应的.so文件的引用。那么,我试着链接.so文件,令我惊讶的是,这工作。另外,当我对生成的二进制文件执行ldd时,.so文件出现了。

所以,我真的很困惑,到底发生了什么。在Windows中,我绝不会想到与.dll文件链接。另外,在Windows中,如果一个.dll文件伴随着一个.lib文件,并且我在编译时与.lib链接,那么我希望在运行时对相应的.dll具有依赖性。这两种情况在这种情况下都是不正确的。

是的,我已经阅读了关于Linux*享对象的基本教程,但是我读的所有内容似乎都表明我最初的假设是正确的。顺便说一下,我应该提及我使用Code :: Blocks作为IDE,但我知道它使事情变得复杂,但我确信当我告诉它与.so文件链接时,它不仅仅是交换.a文件,因为生成的二进制文件较小。 (加上关于LDD的整个业务...)

无论如何,在此先感谢。

我正在链接到.a,但是当我在生成的二进制文件上执行ldd时,它不包含对应的.so文件的引用。

这是预期的。静态链接时,静态库的代码将集成到生成的二进制文件中。没有更多对静态库的引用或依赖关系。

那么,我试着链接到.so文件,令我惊讶的是,这工作。

你是什么意思,静态链接不起作用?没有理由不应该...

+0

不,我很惊讶你可以链接一个动态库。你不能在Windows中链接一个DLL。 – Joey 2018-03-10 22:28:47

.lib在Windows中用于动态链接。你在Linux中没有它们,你直接与.so链接。 .a文件是静态构建的库,您可以使用它来静态链接。

+0

正确,但在很多情况下,.lib和.dll在Windows中配对在一起。 .lib是一个小的存根库,它包含从.dll(即LoadProcAddress)加载实际函数的包装函数。我试图了解这是如何在Linux中的作品。我认为答案是,当你链接到.so文件时,你正在做类似的事情,但可能是错误的。 – Joey 2018-03-10 22:25:39

要添加到tharibo已经正确的答案 - 在某些情况下(例如延迟共享库加载),可能需要以Windows方式进行,即通过链接静态存根而不是.so。这些存根可以通过手工编写,由项目特定的脚本或通用的Implib.so tool生成。