共享库和 .h 文件

新手上路,请多包涵

我对程序如何使用共享库有一些疑问。

当我构建一个共享库(使用 -shared -fPIC 开关)时,我会从外部程序中提供一些功能。通常我会做一个 dlopen() 来加载库,然后 dlsym() 将上述函数链接到一些函数指针。此方法不涉及包含任何 .h 文件。有没有办法避免做 dlopen() & dlsym() 并且只包括共享库的 .h ?

这可能是 c++ 程序如何使用存储在系统共享库中的代码。即只包括stdlib.h等。

原文由 nick2k3 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 338
2 个回答

尼克,我认为所有其他答案实际上都是在回答您的问题,即您如何链接库,但是您提出问题的方式表明您对头文件和库之间的区别存在误解。他们不一样。你需要 _两者_,他们做的不是同一件事。

构建可执行文件有两个主要阶段,编译(将源代码转换为中间形式,包含可执行的二进制指令,但不是可运行的程序)和链接(将这些中间文件组合成单个运行的可执行文件或库)。

当您执行 gcc -c program.c 时,您正在编译,并生成 program.o 。这一步是 标题 很重要的地方。您需要 #include <stdlib.h>program.c 中(例如)使用 mallocfree 。 (同样,您需要 #include <dlfcn.h> 用于 dlopendlsym 。)如果您不这样做,编译器会抱怨它不知道这些名称是什么,并因错误而停止。但是,如果您执行 #include 标头,编译器 不会 将您调用的函数的代码插入 program.o 。它只是插入对它们的 _引用_。原因是为了避免重复代码:程序的每个部分只需要访问一次代码,因此如果您需要更多文件( module1.cmodule2.c 和依此类推),即使他们 使用了 malloc 您最终只会得到对 malloc 的单个副本的许多引用。该单个副本以共享或静态形式( libc.solibc.a )存在于标准 中,但您的源代码中未引用这些副本,编译器不知道它们.

链接器 .在链接阶段,您执行 gcc -o program program.o 。然后,链接器将搜索您在命令行上传递的所有库,并找到您调用的所有未在您自己的代码中定义的函数的 单一 定义。这就是 -l 所做的(正如其他人所解释的那样):告诉链接器您需要使用的库列表。它们的名称通常与您在上一步中使用的标题无关。 For example to get use of dlsym you need libdl.so or libdl.a , so your command-line would be gcc -o program program.o -ldl .要使用 mallocstd*.h 头文件中的大多数功能,您需要 libc ,但是因为 每个 C 程序都使用该库,所以它是 自动 链接的如果您已经完成了 -lc )。

对不起,如果我要详细介绍,但如果你不知道你会想要的区别。如果不这样做,就很难理解 C 编译的工作原理。

最后一件事: dlopendlsym 不是正常的链接方法。它们用于特殊情况,您希望根据信息动态确定您想要的行为,无论出于何种原因,这些信息仅在运行时可用。如果您知道要在编译时调用哪些函数(在 99% 的情况下为真),则不需要使用 dl* 函数。

原文由 quark 发布,翻译遵循 CC BY-SA 2.5 许可协议

您可以链接共享库,例如静态库。然后在启动程序时搜索它们。事实上,默认情况下 -lXXX 会优先选择 libXXX.so 而不是 libXXX.a。

原文由 AProgrammer 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题