是否有可能确定对应于某些头文件的库?

假设我们在同一个目录中有几个头文件和库文件。 如果我不知道应该链接哪个库,可以通过编程来确定哪个库必须被使用。

比方说,我试图编译我的代码,连接器抱怨未解决的外部符号,有什么我可以做,知道正确的库存在于同一目录?

我认为这个问题的答案可能会帮助你很多: 检查.lib文件的工具? 。

你可以编写一个简单的脚本,循环访问目录中的所有lib文件,然后调用dumpbin将所有lib的符号转储到以lib名称开头的文件中,以便以后可以在生成的文件中搜索所需的符号得到正确的lib。

“我可以通过编程确定必须使用哪个库”

不在同一个程序/代码库中 。 “编程”(比如template技巧等)能力一直保持到编译阶段。 一旦链接开始(截至今天),控制权就消失了。

“有什么我可以做的,知道正确的图书馆存在于同一个目录?

再次没有 。 我不打算让你失望,但你所问的不会有帮助。 假设,你设法找到一种方法来知道库是否存在于同一个目录中。 它的目的是什么? 因为实际上一个图书馆可以驻留在任何路径上。 人们只需在gcc中设置MSVC或-L选项中的路径变量即可。 所以把库放在同一个目录下的问题是没有意义的。

也许你可能会问,如何知道图书馆是否存在于你的系统及其中。
那么,这是当然不可能在相同的代码基础上编程。 因为您必须运行该代码库来查找该库是否存在于系统中的某个位置。 要运行该代码库,您必须链接它。 鸡蛋问题。
您可以手动检查或编写自己的单独脚本/代码来执行此任务。

也许它更好地使用C + +中的GetProcAddress函数,或者如果你自己写lib本身,你可以在这样的头添加代码:'#'编译注释(lib,“libname.lib”)希望它的帮助

我最近一直在学习更多的C ++,而且我也有类似的问题。 大多数库和头文件似乎至少有一个类似的名字,但“libm”和“math.h”之间的差异真的让我想知道如何更系统地确定这一点。

对于静态和动态库,我发现有用的工具是readelf ,我喜欢的命令是这样的:

 readelf --symbols <elf_file> | sed -ne '/FUNC/p' 

因此,以我的激励为例:

 $ readelf --symbols /lib/libm.so.5 | sed -ne '/FUNC/p' 2: 0000000000000000 476 FUNC WEAK DEFAULT UND __cxa_finalize@FBSD_1.0 (8) 4: 0000000000000000 62 FUNC GLOBAL DEFAULT UND __isinf@FBSD_1.0 (8) 5: 0000000000000000 310 FUNC GLOBAL DEFAULT UND ldexp@FBSD_1.0 (8) 6: 0000000000000000 41 FUNC GLOBAL DEFAULT UND __isinff@FBSD_1.0 (8) 9: 0000000000000000 8 FUNC GLOBAL DEFAULT UND __tls_get_addr@FBSD_1.0 (8) 11: 0000000000000000 16 FUNC GLOBAL DEFAULT UND __stack_chk_fail@FBSD_1.0 (8) 12: 0000000000000000 53 FUNC GLOBAL DEFAULT UND __isinfl@FBSD_1.0 (8) 14: 0000000000000000 84 FUNC GLOBAL DEFAULT UND memset@FBSD_1.0 (8) 16: 0000000000004ed0 6 FUNC GLOBAL DEFAULT 12 lrintf@@FBSD_1.0 17: 0000000000019930 405 FUNC GLOBAL DEFAULT 12 log10l@@FBSD_1.3 18: 0000000000016590 600 FUNC GLOBAL DEFAULT 12 floorl@@FBSD_1.0 ... 

这个命令也适用于ar档案文件,比如libcurl.a。

所以在这里你可以看到库中定义的函数。 从那里我直观地比较了最后一列中的名字,比如“log10l”和头文件/usr/include/math.h中的名字,并且发现了很高的对应关系。 基于这一点写一个程序似乎是可行的。 解析上面的readelf命令的最后一列,并对/ usr / include中的所有.h文件执行grep。 虽然我没有那么做。

在做了一些与我的回答相关的实验之后,我发现sed命令可能也会根据你的需求进一步改进。 当我在libcurl.a上使用readelf时,也会输出非全局函数(所以不需要包含在头文件中)。