29

我有一个共享对象(so - Windows dll 的 Linux 等效项),我想导入它并与我的测试代码一起使用。

我敢肯定这不是那么简单;)但这是我想做的事情..

#include "headerforClassFromBlah.h"

int main()
{
    load( "blah.so" );

    ClassFromBlah a;
    a.DoSomething();
}

我认为这是一个非常基本的问题,但我找不到任何让我在网上搜索的东西。

4

4 回答 4

48

C++中有两种加载共享对象的方法

对于这两种方法中的任何一种,您总是需要要使用的对象的头文件。标头将包含您要在代码中使用的类或对象的定义。

静态:

#include "blah.h"
int main()
{
  ClassFromBlah a;
  a.DoSomething();
}

gcc yourfile.cpp -lblah

动态(在 Linux 中):

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
    void *handle;
    double (*cosine)(double);
    char *error;
    handle = dlopen ("libm.so", RTLD_LAZY);
    if (!handle) {
        fprintf (stderr, "%s\n", dlerror());
        exit(1);
    }
    dlerror();    /* Clear any existing error */
    cosine = dlsym(handle, "cos");
    if ((error = dlerror()) != NULL)  {
        fprintf (stderr, "%s\n", error);
        exit(1);
    }
    printf ("%f\n", (*cosine)(2.0));
    dlclose(handle);
    return 0;
}

*stolen from dlopen Linux man page windows或其他平台下的流程都是一样的,只是把dlopen换成动态符号搜索的平台版本即可。

要使动态方法起作用,您要导入/导出的所有符号都必须具有外部 C 链接。

这里有一些关于何时使用静态和何时使用动态链接的词。

于 2009-07-17T09:06:33.777 回答
7

这取决于平台。要在运行时执行此操作,在 Linux 上使用dlopen,在 Windows 上使用LoadLibrary

要在编译时执行此操作,请在 Windows 上使用dllexportdllimport导出函数名称。在 linux 上,gcc 导出所有公共符号,因此您可以正常链接到它并调用该函数。在这两种情况下,通常这要求您在头文件中包含符号的名称#include,然后使用编译器的工具链接到库。

于 2009-07-17T08:56:27.307 回答
5

您需要#include 与共享库关联的任何标头,以获取 ClassFromBlah 之类的声明。然后,您需要链接到 .so - 具体操作方式取决于您的编译器和一般安装,但对于 g++,类似:

g++ myfile.cpp -lblah

可能会工作。

于 2009-07-17T08:57:33.450 回答
0

是 -l 链接像 libblah.a 这样的存档文件,或者如果您将 -PIC 添加到 gcc,您将获得一个“共享对象”文件 libblah.so(它是构建它的链接器)。我曾经有过一个 SUN,并且已经构建了这种类型的文件。文件的修订号必须准确或更高(代码可能因错误而更改)。但带参数的调用必须与输出相同。

于 2017-07-10T12:31:04.130 回答