开发者

c++ dynamic library dlopen error

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"


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


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.


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.


Here you have the answer

C++ dlopen mini HOWTO

You have a problem with class methods signature

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜