在另一个共享库中使用共享库

新手上路,请多包涵

我正在从一个示例中的类创建一个共享库,我在这里获得了 C++ Dynamic Shared Library on Linux 。我想从创建的共享库中调用另一个共享库,然后在主程序中使用它。所以我有 myclass.so 库,我想从 myclass.so 库中调用另一个库,比如 anotherclass.so,然后在主程序中使用这个 myclass.so 库。请对我如何做到这一点有任何想法。

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

阅读 746
2 个回答

如果您要自己构建所有库和程序,则可以通过多种方式将多个共享库添加到程序的链接中。

基本的方法是简单地将所有库显式添加到程序的链接中,如果您只构建程序并链接其他方构建的库,这是通常的方式。

如果链接中的目标文件 foo.o 依赖于库 libA.so ,那么 foo.o 应该在 libA.so 序列中的 —f304491.3c8 链接之前同样,如果 libA.so 依赖于 libB.so 那么 libA.so 应该在 libB.so 之前。这是一个插图。

我们将从文件中创建一个共享库 libsquare.so

平方.h

 #ifndef SQUARE_H
#define SQUARE_H

double square(double d);

#endif

正方形.cpp

 #include <square.h>
#include <cmath>

double square(double d)
{
    return pow(d,2);
}

Notice that the function square calls pow , which is declared in the Standard header <cmath> and defined in the math library, libm .

将源文件 square.cpp 编译为与位置无关的目标文件 square.o

 $ g++ -Wall -fPIC -I. -c square.cpp

然后将 square.o 链接到共享库 libsquare.so

 $ g++ -shared -o libsquare.so square.o

接下来,我们将从这些文件中创建另一个共享库 libcube.so

立方体.h

 #ifndef CUBE_H
#define CUBE_H

double cube(double d);

#endif

立方体.cpp

 #include <cube.h>
#include <square.h>

double cube(double d)
{
    return square(d) * d;
}

看到函数 cube 调用 square ,所以 libcube.so 将依赖 libsquare.so 像以前一样构建库:

 $ g++ -Wall -fPIC -I. -c cube.cpp
$ g++ -shared -o libcube.so cube.o

We haven’t bothered to link libsquare with libcube , even though libcube depends on libsquare , and even though we could have, since我们正在建设 libcube 。就此而言,我们没有费心将 libmlibsquare 联系起来。默认情况下,链接器会让我们链接一个包含未定义引用的共享库,这是完全正常的。它 不会 让我们将 程序 与未定义的引用联系起来。

最后,让我们使用这些库从这个文件中创建一个程序:

主文件

#include <cube.h>
#include <iostream>

int main()
{
    std::cout << cube(3) << std::endl;
    return 0;
}

首先,将该源文件编译为 main.o

 $ g++ -Wall -I. -c main.cpp

Then link main.o with all three required libraries, making sure to list the linker inputs in dependency order: main.o , libcube.so , libsquare.so , libm.so

 $ g++ -o prog main.o -L. -lcube -lsquare -lm

libm 是一个系统库,所以不需要告诉链接器在哪里寻找它。但是 libcubelibsquare 不是,所以我们需要告诉链接器在当前目录中查找它们( . ),因为那是它们所在的位置. -L. 这样做。

我们已成功链接 ./prog ,但是:

 $ ./prog
./prog: error while loading shared libraries: libcube.so: cannot open shared object file: No such file or directory

它不运行。那是因为运行时 加载程序 不知道在哪里可以找到 libcube.so (或 libsquare.so ,尽管它没有那么远)。

通常,当我们构建共享库时,我们会将它们安装在加载器的默认搜索目录之一(与链接器的默认搜索目录相同),任何程序都可以使用它们,因此不会发生这种情况。但我不会在我的系统上安装这些玩具库,因此作为一种解决方法,我将通过在我的 shell 中设置 LD_LIBRARY_PATH 来提示加载程序在哪里寻找它们。

 $ export LD_LIBRARY_PATH=.
$ ./prog
27

好的。 3 立方 = 27。

将程序与不在标准系统库目录中的共享库链接的另一种更好的方法是使用链接器的 -rpath=DIR 选项链接程序。这会将一些信息写入可执行文件,以告诉加载程序它应该在 DIR 中搜索所需的共享库,然后再尝试默认位置。

让我们以这种方式重新链接 ./prog (首先从 shell 中删除 LD_LIBRARY_PATH 使其不再有效):

 $ unset LD_LIBRARY_PATH
$ g++ -o prog main.o -L. -lcube -lsquare -lm -Wl,-rpath=.

并重新运行:

 $ ./prog
27

To use -rpath with g++, prefix it with -Wl , because it’s an option for linker, ld , that the g++ frontend doesn’ t 识别: -Wl 告诉 g++ 只是将选项直接传递给 ld

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

只需像在任何其他应用程序中使用它一样使用该库。您不必链接到 anotherclass.so ,只需链接到 --- myclass.so

但是,您必须使这两个库( myclass.so anotherclass.so )可用于您以后的应用程序的运行时。如果其中一个缺失,您将得到运行时错误,就像任何其他应用程序一样。

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

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