我在Linux编程中一直有这个问题。只要Linux的所有手册和几乎所有源代码都是以C为中心的,所有对某些函数的引用只需要一些include <something.h>
行,并且可以从C / C ++代码访问该函数。
但我用汇编语言编程,对C / C ++几乎一无所知。
为了能够调用某个函数,我必须从相应的.so库中导入它。
如何确定库的文件名?它通常不同于库本身的名称,并且未在手册中指定。
例如,XLib的名称实际上是libX11.so.6
。 XShm扩展库的名称似乎是libXext.so.6
。
使用提供的C手册和参考资料,是否有简单的方法来确定库的秘密实名?
答案 0 :(得分:3)
这是另一种不是100%准确的方法,它可以为您提供一些关于如何缩小范围的想法。它没有完全适合这个问题,因为它使用常见的Linux实用程序而不是man文件,但它可能仍然有用。
例如,在Arch Linux上,如果您对GLFW/glfw3.h
中的某个函数感兴趣,可以找出该文件的拥有者:
$ pacman -Qo /usr/include/GLFW/glfw3.h
/usr/include/GLFW/glfw3.h is owned by glfw 3.1-1
找出该软件包中的.so
个文件:
$ pacman -Ql glfw | grep 'so$'
glfw /usr/lib/libglfw.so
并且,如果需要,找到链接指向的实际文件:
$ readlink -f /usr/lib/libglfw.so
/usr/lib/libglfw.so.3.1
这取决于您的发行版。我相信Ubuntu / Debian你会改用dpkg-query
。
修改:DevSolar在评论中指出您可以使用apt-file search <header>
和apt-file list <package>
代替dpkg-query -S <header>
和dpkg-query -L <package>
。 apt-file
似乎适用于尚未安装的软件包(虽然看起来更慢?)。
我还注意到(至少在我的Ubuntu VM上),例如 libglfw-dev 包含libglfw.so
符号链接,而 libglfw2 包含实际libglfw.so.2
对象。
获得一组.so
个文件后,您可以查看它们对您感兴趣的任何功能:
$ nm -D /usr/lib/libglfw.so | grep "glfwCreateWindow"
0000000000007cd0 T glfwCreateWindow
请注意,我从previous question的评论中提取了最后一步,并且完全不了解它。也许你甚至可以跳过前面的步骤,仅依靠nm
和grep
?
答案 1 :(得分:2)
这不是一种确定的消防途径,但在许多情况下它可以提供帮助。
基本上,您通常可以在man
页面的底部找到库名称。
例如,man XCreateWindow
在最后一行显示libX11
。然后,您查找libX11.so
并使用nm
或readelf
查看所有导出的函数。
另一个例子,man XShm
在底部说libXext
。等等。
<强>更新强>
如果该函数位于手册页的第(2)部分,则它是系统调用(参见man man
)并由glibc提供,它将是libc-2.??.so
。
最后(感谢Basile),如果函数没有提到库,它也很可能是由glibc提供的。
免责声明:同样,这不是100%准确的方法 - 但在大多数情况下它应该有所帮助。
答案 2 :(得分:0)
正如我评论的那样,您可以使用gcc
来关联您的计划,然后它应该能够接受-lX11
;使用gcc -v
代替gcc
,您可以找出实际链接的内容以及内容。
但是,与查找lib*.so.*
相比,您有一个更重要的问题;大多数C或C ++ API在头文件中描述,这些C或C ++头文件还包含符号常量(如open(2)的O_RDONLY
...)或宏(如POSIX wait中的WIFEXITED
...)您应在头文件或文档中手动查找其值或扩展名。 (通常,这些常量是预处理器#define
- d常量或enum
值)。此外,一些标题 - 特别是在C ++中 - 包含许多inline
- d函数(或宏)!
一种可能的方法是生成一些C文件来查找所有这些常量,枚举,宏,内联函数......,和/或自定义GCC编译器(例如MELT。 ..)找到它们。
所以我的信息是,无论好坏,C语言深深地与Linux&amp; POSIX。
您可能会限制自己仅使用汇编程序代码中的syscalls(2)。然后你不会使用libX11
而你不需要任何标题或常量(系统调用的除外,从<asm/unistd.h>
开始)。
asm
指令在汇编程序中使用GCC进行编码。
或者您正在构建自己的编译器?那么你应该在你的问题中告诉你了!
答案 3 :(得分:0)
您可以要求gcc
告诉您它将用于链接的文件:
gcc --print-file-name=libX11.so
示例输出:
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/libX11.so
此文件通常是符号链接,因此您必须通过readlink
或realpath
来管理它以获取实际文件。例如:
readlink -f $(gcc --print-file-name=libXext.so)
示例输出:
/usr/lib/x86_64-linux-gnu/libXext.so.6.4.0