假设我们在同一目录中有多个头文件和库文件。如果我不知道应该链接哪个库,我可以通过编程方式确定必须使用哪个库。
让我说我试图编译我的代码,并且链接器抱怨未解析的外部符号,我能做什么,知道正确的库存在于同一目录中吗?
答案 0 :(得分:5)
我认为这个问题的答案可能会对你有所帮助:Tools for inspecting .lib files?。
您可以编写一个简单的脚本,循环遍历目录中的所有lib文件,并调用dumpbin将所有库的符号转储到以lib名称开头的文件中,以便稍后您可以搜索所需的符号。生成文件以获取正确的lib。
答案 1 :(得分:2)
"我可以通过编程方式确定必须使用哪个库。"
不在同一程序/代码库中。 "程序化" (说template
技巧等)能力一直持续到编译阶段。一旦链接开始(截至今天),控件就消失了。
"我知道同一目录中存在正确的库吗?"
再次否。我并不打算让你失去动力,但无论如何你所要求的并不会有所帮助。假设,您设法找到一种方法来了解库是否存在于同一目录中。它的目的是什么?因为实际上库可以驻留在任何路径中。只需在MSVC中设置路径变量或在gcc中设置-L
选项。因此,将库放在同一目录中的问题没有实际意义。
可能您可能想问一下,如何知道您的系统中是否存在库?在那里。
嗯,这在同一代码库中不可能以编程方式进行。因为您必须运行该代码库以查找库是否存在于系统中的某个位置。要运行该代码库,您必须链接它。鸡蛋问题。
您可以手动检查或编写自己的单独脚本/代码来执行此任务。
答案 2 :(得分:0)
使用dll可能更好 GetProcAddress function in C++ 或者如果您自己编写lib,您可以在头文件中添加代码,如下所示: '#" pragma comment(lib," libname.lib") 希望它的帮助
答案 3 :(得分:0)
我最近一直在学习更多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
时,也会输出非全局函数(因此,不需要包含在头文件中的函数)。