简单的共享库

时间:2010-10-26 17:54:01

标签: c++ linux shared-libraries

  1. STD库是共享库还是它是什么?出于好奇心。
  2. 是否有任何书籍详细描述了共享的静态库开发?
  3. 有没有教程?
  4. p.s(我正在使用netbeans,eclipse,anjuta)并且教程没有用,因为我正在试图了解实际发生了什么。

2 个答案:

答案 0 :(得分:7)

在我的平台上(Ubuntu Maverick),它是:

g++ test.cpp
ldd a.out

linux-vdso.so.1 =>  (0x00007fffee1ff000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f18755fd000)
libm.so.6 => /lib/libm.so.6 (0x00007f187537a000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f1875163000)
libc.so.6 => /lib/libc.so.6 (0x00007f1874de0000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1875920000)

注意上面的libstdc ++。so.6。

使用cmake创建共享库非常容易。

1。 安装cmake 2.6或更高版本。

2。 使用库的代码创建文件test.cpp。

3。 创建一个文件CMakeLists.txt:

cmake_minimum_required(VERSION 2.6)
project(TEST)
add_library(test SHARED test.cpp)

4。 运行cmake以创建一个makefile:

cmake -G "Unix Makefiles"

5。 运行make来构建共享库。

使用CMake,您还可以使用以下命令生成Eclipse CDT项目

cmake -G "Eclipse CDT4 - Unix Makefiles"

您还可以找到有关该主题的有趣文章,并提供更多参考文献here

答案 1 :(得分:2)

1。)STD库是共享库还是它是什么?

我不知道。可能是。可能两者都有。有关系吗?除非你正在处理一些非常奇特的东西,比如一个独立的静态链接二进制文件用于系统重建,只要编译器/系统知道如何链接它,你就不太可能关心它。


简而言之,代码可以在静态库中,在这种情况下,它可以链接到最终(已编译/生成)的可执行文件中,并且这些二进制文件可能会变得非常大。或者它可以在共享库中,在这种情况下,库是动态加载的,并且多个应用程序可以(理论上)共享一个公共存储器映像。除非您正在做一些非常大的事情,并且将在多个应用程序之间共享,否则我会质疑使用共享库的智慧。额外的头痛,特别是调试头痛,很少值得。没有多个并发运行的应用程序,就没有节省......


要创建一个静态库,我会将一堆文件编译成目标文件...比使用 ar randlib 即可。 E.g:

g++ -c foo1.C -o foo1.o
g++ -c foo2.C -o foo2.o
ar -rv libfoo.a foo1.o foo2.o
ranlib libfoo.a

随后,我只是将该库链接到:

g++ testfoo.C -o testfoo -L. -lfoo

请注意,如果您使用多个库,那么(g ++ testfoo.C)命令行中 -lbar1 -lbar2 的顺序很重要!它确定哪些库可以调用其他库中的函数/方法。循环依赖是 BAD

关于 foo1.o foo2.o 文件到 ar ,排序没有区别。


动态库......

前一段时间,在一个古老的fedora core 3系统下,我正在玩linux下的共享库。那时候,我会编译我的共享库,比如 fooLibrary.c ,用:

g++ -shared -Wl,-soname,libfooLibrary.so.1 -o libfooLibrary.so.1.0 -fPIC fooLibrary.c -ldl

那时我正在玩LD_PRELOAD,所以我有一个小脚本来运行我的程序:

export LD_PRELOAD=libfooLibrary.so ; export LD_LIBRARY_PATH=. ; ./myTestProgram

(请注意,在运行 g ++ ls NOT 想要设置 LD_PRELOAD > cd 等,因为我正在拦截系统调用。)

(仅供参考: strace 也很有趣...你还应该看看 ldd nm 。)

您可能需要手动查看 dlopen() dlsym() 等内容访问动态库......

哦,环境变量 LD_LIBRARY_PATH 将目录添加到动态库的默认搜索路径中......

(关于调试,我只想提一下,当我截获 malloc()时,我发现 dlopen()/ dlsym()中的某个地方被调用 malloc()。在我手动加载提供真正的 malloc()的库之前,我需要使用 malloc()。调试一次......)


PS还有一个想法:您可能想要查看 gcc / g ++ 的命令行选项。那里有很多有用的信息......

http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/index.html#toc_Invoking-GCC