如何在C++中加载共享对象?

Ben*_*n L 20 c++ load shared-objects

我有一个共享对象(因此 - 相当于Windows dll的Linux),我想导入并使用我的测试代码.

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

#include "headerforClassFromBlah.h"

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

    ClassFromBlah a;
    a.DoSomething();
}
Run Code Online (Sandbox Code Playgroud)

我认为这是一个非常基本的问题,但是在搜索网页时我找不到任何跳出来的东西.

Sal*_*gar 40

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

对于这些方法中的任何一种,您始终需要要使用的对象的头文件.标题将包含要在代码中使用的类或对象的定义.

静态:

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

gcc yourfile.cpp -lblah
Run Code Online (Sandbox Code Playgroud)

动态(在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;
}
Run Code Online (Sandbox Code Playgroud)

*从dlopen Linux手册页中窃取 windows或任何其他平台下的进程是相同的,只需用动态符号搜索的平台版本替换dlopen.

要使动态方法起作用,您要导入/导出的所有符号必须具有extern'd C链接.

有一些词在这里何时使用静态以及何时使用动态链接.

  • +1.也许值得一提的是dlopen是POSIX,而不是C或C++.在某些平台上没有动态加载,但它们仍然符合C++实现. (5认同)
  • 请注意, dlsym(handle, "cos") 引用了一个 C 函数,因此很容易找到名称。C++ 会生成装饰,使此类代码不那么容易编写。(至少在不使用 extern "C" 扩展的情况下不能,所以编写一个 C 函数来获取 C++ 函数。) (2认同)

180*_*ION 5

这取决于平台.要在运行时,在Linux上使用dlopen,在Windows上使用LoadLibrary.

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


小智 5

您需要 #include 与共享库关联的任何标头,以获取诸如 ClassFromBlah 之类的声明。然后你需要链接到 .so - 你如何做到这一点取决于你的编译器和一般安装,但对于 g++ 是这样的:

g++ myfile.cpp -lblah
Run Code Online (Sandbox Code Playgroud)

可能会工作。