2

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

这是我到目前为止所拥有的:

扩展模块.h

    #include <list>
    #include <string>

    using namespace std;

    class ExtModule
    {
    public:
        ExtModule();

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

模块文件.cpp

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

主文件

#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 库中检索多个列表,但我不知道这是否是正确的方法。此外,正如您可能已经猜到的那样,我不是特别熟练的程序员。任何建议将不胜感激。

感谢您的任何帮助。

4

2 回答 2

1

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

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

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

和你的插件

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

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

在实践中,Qt 知道插件并且qmake也有插件支持。

如果使用dlopen&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 Libraries高级 Linux 编程书籍。

顺便说一句,您不会显示所有 C++ 代码。请确保您具有所需的构造函数和析构函数。阅读关于在C++11中成为五规则的三规则(对于旧的 C++03) 。

于 2014-05-04T11:23:56.330 回答
0

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

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

于 2015-03-30T13:06:19.360 回答