【问题标题】:C++ using functions from shared libraryC++ 使用来自共享库的函数
【发布时间】:2018-09-29 13:27:27
【问题描述】:

我有以下问题:

我有两个独立的 c++ 项目,并且想在另一个中使用其中一个的某些功能。我在 Linux 上使用 g++ 进行编译。

我决定通过在项目之外创建一个共享库来使用这些函数来做到这一点。我将 -fPIC 添加到 Makefile 中的编译器标志,然后创建了一个这样的共享库:

g++ -shared -Wl,-soname,libmyproject.so.1 -o libmyproject.so a.o b.o c.o -lc

然后我简单地将 .so 文件和头文件复制到新项目的(父)目录中,并将以下内容添加到其 Makefile 中:

致 LIBS:

-L/../external_proj/libmyproject.so

致 CXXFLAGS:

-I/../external_proj

然后我在目标项目代码中#include 适当的头文件并尝试从原始项目中调用某些函数。但是,当我编译目标项目时,我收到导入函数的错误“未定义引用”。

然后我的问题是:我在这个设置中缺少什么吗?为了导出我想要使用的功能,是否可能需要将某些内容添加到原始项目的标题中?

我应该注意到这是我第一次尝试以这种方式使用共享库。谢谢。

【问题讨论】:

    标签: c++ shared-libraries


    【解决方案1】:

    -L 选项仅指定链接器将在其中搜索要链接的库的目录。然后您需要使用-l 选项来指定共享库的基本名称(不带“lib”前缀和“.so”后缀)。

    但即使这样也不太可能足够。当您尝试执行时,运行时加载程序需要找到共享库。 -L-l 足以成功链接,但运行时加载程序默认只搜索 /usr/lib(64)? 和其他几个地方。它不搜索当前目录,ELF 二进制文件只记录必须加载的共享库的名称,而不是它们的完整路径名。您必须显式记录任何额外的目录才能搜索任何共享库,这是 -rpath 选项。

    要完成这项工作,您还需要将-rpath 传递给链接器,但g++ 不支持此选项目录,您必须使用-W 来执行此操作。

    您可能需要的全套选项包括:

    -L/../external_proj -lmyproject -Wl,-rpath -Wl,`cd ../external_proj && pwd`
    

    有关-W 选项的更多信息,请参阅 gcc 文档。

    绝对路径名应与-rpath 一起使用,因此需要获取共享库所在目录的完整路径名。

    【讨论】:

    • 执行 readelf -a <program> | grep PATH 以查看为您的可执行文件设置的共享库搜索路径。这将告诉您您的 rpath 是否设置正确。
    • 对不起,删除了我之前的评论尝试一下。通过将完整的 -Wl 命令从 CXXFLAGS 移动到另一个变量 LDFLAGS,解决了运行时加载问题。非常感谢。
    【解决方案2】:

    -L 标志用于添加 路径 以在其中搜索库。-l(小写 L)用于链接搜索路径中的库。

    或者您可以跳过标志并直接与库链接,就像您现在所做的一样(但没有-L 选项)。


    如果您使用-l 选项,请记住对于文件libname.so,您只使用name 作为库名称。如-lname。链接器将搜索添加了前缀和后缀的正确文件。


    最后,关于链接时使用的路径的重要说明:如果您使用-L-l 链接共享库,则只有链接器会找到该库。如果库位于非标准位置,操作系统运行时加载器将能够看到使用的路径并且找不到库。为此,您还必须使用特殊链接器选项 -rpath 设置 runtime-path

    不幸的是,GCC 前端程序g++ 无法识别该选项,您必须使用-Wl 告诉g++ 将选项传递给实际的链接器。如-Wl,-rpath,/path/to/libraries

    总而言之,以下是您可以使用的不同变体:

    • 直接与库链接:g++ your_source.cpp ../external_proj/libmyproject.so
    • 使用-L-l 选项:g++ your_source.cpp -L../external_proj -lmyproject
    • 设置运行时链接器路径:g++ your_source.cpp -L../external_proj -lmyproject -Wl,-rpath,../external_proj

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 2017-10-07
      • 1970-01-01
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      相关资源
      最近更新 更多