繁体   English   中英

c++动态库dlopen错误

[英]c++ dynamic library dlopen error

我有两个文件:RollDice.cpp

#include "RollDice.h"
#include "./IPlugins.cpp"
#include "./IPluginFunctions.cpp"

#include <iostream>

RollDice::RollDice(IPluginFunctions &iPluginFunctions) :
    IPlugins(iPluginFunctions) {
    //srand(time(NULL));
}

RollDice::~RollDice() {

}

void RollDice::callPlugin(std::string paramsText, std::string dataText) {
    std::cout << "RollDice ;)\n";
}

RollDice.h:

#ifndef ROLLDICE_H_
#define ROLLDICE_H_
#include "./IPlugins.h"
#include "./IPluginFunctions.h"

class RollDice: public IPlugins {
public:
    RollDice(IPluginFunctions &iPluginFunctions);
    virtual ~RollDice();

    virtual void callPlugin(std::string paramsText, std::string dataText);
};

extern "C" RollDice* create(IPluginFunctions &iPluginFunctions) {
    return new RollDice(iPluginFunctions);
}

extern "C" void destroy(RollDice *rollDice) {
    delete rollDice;
}

#endif /* ROLLDICE_H_ */

我创建.so 文件:g++ -shared -o RollDice.so RollDice.cpp

现在在我的应用程序中,我想打开这个插件:

this->plugin = dlopen(directory.c_str(), RTLD_LAZY);
    if (!(this->plugin)) {
        std::cerr << "Cannot load library: " << dlerror() << '\n';
        return;
    }

    dlerror();

    this->createPlugin = (create_p*) dlsym(plugin, "create");
    const char* dlsymError = dlerror();
    if (dlsymError) {
        std::cerr << "Cannot load symbol create: " << dlsymError << '\n';
        return;
    }

    this->destroyPlugin = (destroy_p*) dlsym(plugin, "destroy");
    dlsymError = dlerror();
    if (dlsymError) {
        std::cerr << "Cannot load symbol destroy: " << dlsymError << '\n';
        return;
    }

但我收到消息:无法加载库:./RollDice.so: invalid ELF header

你能帮我解决这个问题吗?

-fPIC

没有帮助

编辑:

现在我正在构建插件:

g++ -shared -fPIC -o RollDice.so RollDice.h IPlugins.cpp IPluginFunctions.cpp

我有新问题:无法加载符号创建:./RollDice.so:未定义符号:创建

当我使用nm查看 RollDice 中有哪些符号时,我看不到“创建”

要检查的似乎还没有提到的一件事是,必须从您的共享库中导出确切的名称“create”。

尝试

nm --dynamic --defined-only RollDice.so | grep create

如果你没有得到匹配,或者得到一些'create'的错位符号,那么你的 dlsym(..., "create") 调用肯定会失败。

此外,一旦您解决了名称查找问题,您应该认真考虑将 RTLD_GLOBAL 添加到您的 dlopen 标志中。 dlopen 默认为 RTLD_LOCAL,它与 C++ 共享库 w.r.t 的交互很差。 RTTI、异常、typeinfo 等 RTLD_GLOBAL 会导致更少的意外。

还可以考虑使用 RTLD_NOW 而不是 RTLD_LAZY。 如果您的插件库中有在 dlopen 时无法解析的符号,则您刚刚创建了一个定时炸弹。 最好在 dlopen 时知道该库是否能够满足所有必需的引用。

编辑:

我忽略了已经建议使用“nm”检查“create”。 但是 dlopen flags 建议仍然很重要。

此外,您的编译行对我来说看起来很奇怪,尤其是您在构建行中包含了 RollDice.h,而不是 RollDice.cpp 文件。

此外,在 other.cpp 文件中包含 .cpp 文件不是标准做法。

我建议消除 .cpp 到 .cpp 的包含,然后使用 -o 分别编译各种.cpp 文件,然后将它们合并到共享库中:

g++ -g -fPIC -c -o RollDice.o RollDice.cpp
g++ -g -fPIC -c -o IPluginFunctions.o IPluginFunctions.cpp
g++ -g -fPIC -c -o IPlugins.o IPlugins.cpp
g++ -g -fPIC -shared -o RollDice.so RollDice.o IPluginFunctions.o IPlugins.o

您没有使用 -fPIC 构建共享库来生成 position 独立代码,共享库需要 IIRC。

一个快速的谷歌加强了我的预感: http://www.fpx.de/fp/Software/tcl-c++/tcl-c++.html

所以使用:

g++ -shared -fPIC -o RollDice.so RollDice.cpp

看看这是否有帮助。

导致此类错误的另一件事是当您尝试使用为不同架构构建的库时(例如 ARM、32、64 等),但我假设您没有在不同的环境中构建 plugin.so您正在编译核心程序的那个。

不确定问题出在哪里,但readelfobjdump等工具可能会提供有关二进制文件 state 的信息,可以帮助您解决问题。

在这里你有答案

C++ dlopen mini HOWTO

class 方法签名有问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM