我想说的是,我从来没有使用过动态库,因此我什至可能不了解它们如何正常工作。

我想运行一个完全加载的代码,并在进行一些触发(可能是用户交互)之后,想加载一个特定的库并在该库中执行一个函数。最好事后将其关闭。从本质上讲,允许我在运行时进行更改并重新加载。

这是简单的动态库(称为dynlib.so与主代码位于同一目录中):

int getInt(int arg_0)
{
  return (arg_0 + 7);
}

这是主程序:
#include <iostream>
#include <dlfcn.h>

int main() {
  void *lib_handle = dlopen("./dynlib.so", RTLD_LAZY | RTLD_NOW);
  if (!lib_handle) {
    fprintf(stderr, "%s\n", dlerror());
    exit(EXIT_FAILURE);
  }

  typedef int (*func_ptr)(int);
  func_ptr func = (func_ptr)dlsym(lib_handle, "getInt");
  std::cout << func(13);

  dlclose(lib_handle);
}

我正在使用以下命令进行编译:g++ -std = c++ 11 -ldl loadlibtest.cpp -o main。

我捕获的错误是./libshared.so:文件太短在我的if (!lib_handle) {中。

最佳答案

这对我来说可以。我已经用dynlib.so编译了

$ gcc dynlib.c -fPIC -shared -o dynlib.so

(显然,您需要使用extern "C"将其编译为C或C++,以避免名称困惑)。

我需要在-ldl调用中将g++放在源文件之后。

gcc:4.8.5; g++:5.3.0
dlsym可能也会失败,并且从void *强制转换为函数指针在技术上是UB。您应该基于usage snippet from themanpage(针对您的函数进行了修改):
       dlerror();    /* Clear any existing error */

       /* Writing: func = (int (*)(int)) dlsym(handle, "getInt");
          would seem more natural, but the C99 standard leaves
          casting from "void *" to a function pointer undefined.
          The assignment used below is the POSIX.1-2003 (Technical
          Corrigendum 1) workaround; see the Rationale for the
          POSIX specification of dlsym(). */

       *(void **) (&func) = dlsym(handle, "getInt");

       if ((error = dlerror()) != NULL)  {
           fprintf(stderr, "%s\n", error);
           exit(EXIT_FAILURE);
       }

09-06 23:13