2

私は2つのファイルを持っています: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:無効なELFヘッダー

これを解決するのを手伝ってもらえますか?

-fPIC

助けにはならない

編集:

今、私はプラグインを構築しています:

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

そして私は新しい問題を抱えています:シンボルをロードできませんcreate:./ RollDice.so:未定義のシンボル:create

nmRollDiceにどのシンボルがあるかを確認するために使用すると、「作成」が表示されません

4

4 に答える 4

2

まだ言及されていないように思われることを確認する1つのことは、正確な名前「create」を共有ライブラリからエクスポートする必要があるということです。

試す

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

一致するものがない場合、または'create'のマングルされたシンボルを取得した場合、dlsym(...、 "create")呼び出しは失敗します。

また、名前検索の問題を解決したら、dlopenフラグにRTLD_GLOBALを追加することを真剣に検討する必要があります。dlopenのデフォルトはRTLD_LOCALです。これは、RTTI、例外、typeinfoなどのC ++共有ライブラリとの相互作用が不十分です。RTLD_GLOBALを使用すると、サプライズが少なくなります。

RTLD_LAZYではなくRTLD_NOWの使用も検討してください。プラグインライブラリにdlopen時に解決できなかったシンボルがある場合は、時限爆弾を作成したばかりです。ライブラリが必要なすべての参照を満たすことができたかどうかをdlopen時に知ることをお勧めします。

編集:

「nm」で「create」をチェックすることがすでに提案されていることを私は見落としていました。ただし、dlopenフラグのアドバイスは依然として重要です。

また、コンパイル行は私には非常に奇妙に見えます。特に、RollDice.cppファイルではなくRollDice.hをビルド行に含めている場合はそうです。

さらに、他の.cppファイルに.cppファイルを含めることは標準的な方法ではありません。

.cppから.cppへの包含を削除し、さまざまな.cppファイルを-oで個別にコンパイルしてから、それらを共有ライブラリにマージすることをお勧めします。

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
于 2011-06-10T13:39:20.627 に答える
1

-fPICを使用して共有ライブラリを構築し、位置に依存しないコードを生成しませんでした。これは、共有ライブラリでIIRCが必要とします。

簡単なグーグルは私の予感を補強します:http ://www.fpx.de/fp/Software/tcl-c ++ /tcl-c++。html

したがって、以下を使用します。

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

そして、それが役立つかどうかを確認してください。

この種のエラーを引き起こすもう1つの原因は、さまざまなアーキテクチャ(ARM、32、64など)用にビルドされたライブラリを使用しようとしている場合ですが、プラグイン.soを別の環境でビルドしていないと想定しています。コアプログラムをコンパイルしているもの。

于 2011-06-10T11:24:06.120 に答える
1

問題が何であるかはわかりませんが、 readelfobjdumpなどのツールは、問題の解決に役立つ可能性のあるバイナリの状態に関する情報を提供する場合があります。

于 2011-06-10T13:12:06.753 に答える
0

ここに答えがあります

C ++ dlopen mini HOWTO

クラスメソッドのシグネチャに問題があります

于 2011-06-10T12:47:31.743 に答える