c++ dynamic library dlopen error

a 夏天 提交于 2019-12-22 18:52:48

问题


I have two files: 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_ */

I create .so file with: g++ -shared -o RollDice.so RollDice.cpp

And now in my application I want to open this plugin:

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;
    }

But I get message: Cannot load library: ./RollDice.so: invalid ELF header

Can you help me solving this?

-fPIC

doesn't help

Edit:

Now I'm bulding plugin with:

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

and I have new problem: Cannot load symbol create: ./RollDice.so: undefined symbol: create

When I use nm to see what symbols are in RollDice.so I don't see "create"


回答1:


One thing to check that doesn't seem to have been mentioned yet is that the exact name 'create' must be exported from your shared library.

Try

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

If you get no matches, or get some mangled symbol for 'create', then your dlsym(..., "create") call is bound to fail.

Also, once you solve the name lookup issues, you should seriously consider adding RTLD_GLOBAL to your dlopen flags. dlopen defaults to RTLD_LOCAL, which interacts poorly with C++ shared libraries w.r.t. RTTI, exceptions, typeinfo, etc. RTLD_GLOBAL will lead to fewer surprises.

Also consider using RTLD_NOW rather than RTLD_LAZY. If there are symbols in your plugin library that were not resolvable at dlopen time, you have just created a ticking time bomb. Better to know at dlopen time whether the library was able to satisfy all of the required references or not.

edit:

I overlooked that checking for 'create' with 'nm' had already been suggested. However the dlopen flags advice is still important.

Also, your compilation line looks very odd to me, especially that you are including the RollDice.h on the build line, rather than the RollDice.cpp file.

In addition, including .cpp files in other .cpp files is not standard practice.

I'd suggest eliminating the .cpp to .cpp inclusion, and then compiling the various .cpp files separately with -o, then merging them into a shared library:

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



回答2:


You didn't build your shared lib using -fPIC to produce position independent code, which IIRC is required by shared libraries.

A quick google reinforces my hunch: http://www.fpx.de/fp/Software/tcl-c++/tcl-c++.html

So use:

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

And see if that helps.

The other thing that causes errors of that sort are when you are trying to use libraries built for different architectures (eg ARM, 32, 64, etc), but I am assuming you aren't building the plugin .so in a different environment to the one which you are compiling the core program.




回答3:


Not sure what the problem is but tools like readelf and objdump might provide information on the state of the binary that may help you resolve your issues.




回答4:


Here you have the answer

C++ dlopen mini HOWTO

You have a problem with class methods signature



来源:https://stackoverflow.com/questions/6305554/c-dynamic-library-dlopen-error

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!