在另一个共享库中使用共享库 [英] Using a shared library in another shared library

查看:146
本文介绍了在另一个共享库中使用共享库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从这里得到的示例中的类创建共享库 C ++ Dynamic Linux上的共享库。我想从创建的共享库中调用另一个共享库,然后在主程序中使用它。因此,我有myclass.so库,我想从myclass.so库中调用另一个库,例如anotherclass.so,然后在主程序中使用此myclass.so库。关于如何执行此操作的任何想法。

I am creating a shared library from a class from an example I got here C++ Dynamic Shared Library on Linux. I would like to call another shared library from the shared library created and then use it in the main program. So I have the myclass.so library and I want to call another library say anotherclass.so from the myclass.so library and then use this myclass.so library in the main program. Any idea on how I can do this please.

推荐答案

可以使用多种方法将多个共享库添加到
是程序的链接,如果您正在构建所有库,则程序自己是

There is more than one way in which multiple shared libraries may be added to the linkage of a program, if you are building all the libraries, and the program, yourself.

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

The elementary way is simply to explicitly add all of the libraries to the the linkage of the program, and this is the usual way if you are building only the program and linking libraries built by some other party.

如果链接中的对象文件 foo.o 取决于库 libA.so ,然后
foo.o 在链接序列中应位于 libA.so 之前。同样,如果 libA.so
取决于 libB.so ,则 libA.so 应该在 libB.so 之前。这是一个例子。

If an object file foo.o in your linkage depends on a library libA.so, then foo.o should precede libA.so in the linkage sequence. Likewise if libA.so depends on libB.so then libA.so should precede libB.so. Here's an illustration.

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

We'll make a shared library libsquare.so from the files:

square.h

#ifndef SQUARE_H
#define SQUARE_H

double square(double d);

#endif

square.cpp

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

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

请注意,函数 square 调用 pow ,该声明在
标准头文件< cmath> 中声明,并在数学库 libm

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

Compile the source file square.cpp to a position-independent object file square.o:

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

然后链接 square.o 进入共享库 libsquare.so

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

接下来,我们将创建另一个共享库<$ c $这些文件中的c> libcube.so :

Next we'll make another shared library libcube.so from these files:

cube.h

#ifndef CUBE_H
#define CUBE_H

double cube(double d);

#endif

cube.cpp

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

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

请参见函数 cube 调用 square ,因此 libcube.so 要转到
取决于 libsquare.so 。像以前一样构建库:

See that the function cube calls square, so libcube.so is going to depend on libsquare.so. Build the library as before:

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

即使 libcube libsquare libcube 链接。 $ c>
取决于 libsquare ,即使我们可以,因为我们正在构建 libcube
因此,我们不必费心将 libm libsquare 链接。默认情况下,
链接器将使我们链接包含未定义引用的共享库,并且
是完全正常的。它不会让我们将程序与未定义的引用链接起来。

We haven't bothered to link libsquare with libcube, even though libcube depends on libsquare, and even though we could have, since we're building libcube. For that matter, we didn't bother to link libm with libsquare. By default the linker will let us link a shared library containing undefined references, and it is perfectly normal. It won't let us link a program with undefined references.

最后,让我们使用这些文件制作程序库,来自此文件:

Finally let's make a program, using these libraries, from this file:

main.cpp

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

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

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

First, compile that source file to main.o:

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

然后链接 main.o 具有所有三个必需的库,请确保按依赖性顺序列出
链接器输入: main.o libcube.so libsquare.so libm.so

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 是系统库,因此无需告诉链接器在哪里寻找
。但是 libcube libsquare 不是,所以我们需要告诉链接器在其中寻找
。当前目录(),因为它们在那里。 -L。做到了。

libm is a system library so there's no need to tell the linker where to look for it. But libcube and libsquare aren't, so we need to tell the linker to look for them in the current directory (.), because that's where they are. -L. does that.

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

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

它不运行。这是因为运行时 loader 不知道在哪里找到 libcube.so (或 libsquare.so ,尽管距离还远)。

It doesn't run. That's because the runtime loader doesn't know where to find libcube.so (or libsquare.so, though it didn't get that far).

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

Normally, when we build shared libraries we then install them in one of the loader's default search directories (the same ones as the linker's default search directories), where they're available to any program, so this wouldn't happen. But I'm not going to install these toy libraries on my system, so as a workaround I'll prompt the loader where to look for them by setting the LD_LIBRARY_PATH in my shell.

$ export LD_LIBRARY_PATH=.
$ ./prog
27

好。 3 cubed = 27。

Good. 3 cubed = 27.

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

Another and better way to link a program with shared libraries that aren't located in standard system library directories is to link the program using the linker's -rpath=DIR option. This will write some information into the executable to tell the loader that it should search for required shared libraries in DIR before it tries the default places.

以这种方式重新链接 ./ prog (首先删除 LD_LIBRARY_PATH ,因此不再有效):

Let's relink ./prog that way (first deleting the LD_LIBRARY_PATH from the shell so that it's not effective any more):

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

然后重新运行:

$ ./prog
27

要使用 -rpath 与g ++,在其前面加上 -Wl 前缀,因为它是链接器 ld
g ++ 前端无法识别: -Wl 告诉 g ++ 只是将
选项直接传递给 ld

To use -rpath with g++, prefix it with -Wl, because it's an option for linker, ld, that the g++ frontend doesn't recognise: -Wl tells g++ just to pass the option straight through to ld.

这篇关于在另一个共享库中使用共享库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆