使用dlopen()和dlsym()从C ++中的.so库中获取对象

时间:2014-05-04 09:55:23

标签: c++ linux dlopen dlsym

我正在尝试在Linux下的Qt应用程序中加载.so文件。这是使用dlopen()和dlsym()为基本功能。但我需要从.so库中获取多个字符串列表,所以我尝试使用常见的.h文件,但我无法从主应用程序访问该对象。

这是我到目前为止所做的:

extmodule.h

    #include <list>
    #include <string>

    using namespace std;

    class ExtModule
    {
    public:
        ExtModule();

        list<string> L2MACSource;
        list<string> L2MACDest;
...

modulefile.cpp

#include "extmodule.h"
extern "C" ExtModule getCont() {
  ExtModule modul;
  modul.L2MACSource.push_back("...")
  return modul;
}
extern "C" void hello()
{
   cout << "hello" << endl;
}

的main.cpp

#include "extmodule.h"
   ...
   dlopen("...../modulefile.so", RTLD_LAZY);
   ...
   typedef ExtModule(*loadedFunc)();
   loadedFunc ext_get = (loadedFunc)dlsym(ext_mod, "getCont");

   typedef void (*hello_t)();
   hello_t hello = (hello_t)dlsym(ext_mod, "hello");

   hello();
   ExtModule modul = ext_get();

hello()函数完美无缺,但我无法使ext_get()工作(/external.so:未定义的符号:_ZN9ExtModuleC1Ev)。我必须从.so库中检索多个列表,但我不知道这是否是正确的方法。另外,正如你可能已经猜到的那样,我并不是特别熟练的程序员。任何建议都将受到高度赞赏。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您可能需要使用-rdynamic标志编译和链接主程序(要求链接器发出动态符号,以便插件可以看到主程序中的名称),例如

 g++ -Wall -rdynamic -g main.cpp -o mainprog

上面可能缺少一些库和其他标志,例如:对于Qt

和你的插件

 g++ -Wall -shared -g -fPIC modulefile.cpp -o module.so

也许上面还缺少其他标志,例如:对于Qt

在实践中,Qt知道pluginsqmake也有插件支持。

如果使用dlopen&amp; 始终 dlsym应检查错误:

 ext_mod = dlopen("...../modulefile.so", RTLD_LAZY);
 if (!ext_mod) { 
   fprintf(stderr, "dlopen failure: %s\n", dlerror()); 
   exit (EXIT_FAILURE); }

以及

 hello_t hello = (hello_t)dlsym(ext_mod, "hello");
 if (!hello) { 
   fprintf(stderr, "dlsym failure: %s\n", dlerror()); 
   exit (EXIT_FAILURE); }

阅读dlopen(3)Program Library HowToC++ dlopen mini howto,Drepper的论文:How To write Shared LibrariesAdvanced Linux Programming本书。

顺便说一句,你没有显示所有的C ++代码。请确保您拥有所需的构造函数和析构函数。阅读rule of three(对于旧的C ++ 03),它成为C++11中的五条规则。

答案 1 :(得分:0)

您可以使用以下命令生成* .so文件。

g ++ -shared -fPIC -o {libname} .so -l {名称* .so文件,其中包含ExtModule的定义} -L {模块的路径。}