1

gcc で共有ライブラリをコンパイルし、メインにリンクしました。メイン クラスは、共有ライブラリ内に表示されるロガー クラスを初期化する必要がありますが、共有ライブラリに独自のインスタンスがあるように見えます。

インクルード ファイルは次のようになります。

extern Log gLog;

主に宣言されています。

Log gLog(new StreamWriter());

リンクしようとするとundefined symbol _gLog、共有ライブラリでリンカー エラーが発生します。クラスインスタンスだからかなと思ってポインタに変えてみたのですが、やはり同じです。さらに悪いことに、共有ライブラリに同じグローバル変数を作成し、それを初期化する関数を呼び出す小さなダミー モジュールを作成できると考えました。しかし、この関数では、メインに表示されないため、リンカ エラーも発生します。

共有ライブラリで:

Log *gLogger;

int initLibrary(Log *pLogger)
{
    gLogger = pLogger;
}

そして主に:

Log gLog(new StreamWriter());
int initLibrary(Log *pLogger);
main()
{
    initLibrary(&gLog);
}

ここでも、リンカーで未定義のシンボルを取得します。今回は initLibrary 関数です。

今のところ、機能するダミー クラスを作成して問題を解決します。ただし、私の理解が間違っているように見えるため、共有ライブラリの境界を越えてシンボルを適切に定義する方法を知りたいです。

Google を使用しているときに、ここでいくつかのスレッドを見つけました。例として、共有ライブラリでグローバル変数を使用し、グローバル変数、共有ライブラリ、および -fPIC 効果を使用します (この問題には他にもいくつかあります)。ただし-fpic、メインモジュールも含めてすべてを再コンパイルしようとしましたが、まだ機能しません。オプションは不明なので、-rdynamicこれがどこから来たのかわかりません。

共有ライブラリのクラスを使用でき、その逆も可能であるため、これはグローバル シンボルにのみ影響します。メインコードと共有ライブラリがシンボルを相互に認識できないというのは、何が間違っているのでしょうか?

4

3 に答える 3

0

他の共有ライブラリまたはメイン プログラムから見えるようにするには、デフォルトの可視性で変数を宣言する必要があります。-fvisibility=hiddenライブラリ内のシンボルがメイン プログラムまたは他のライブラリ内の定義に解決されず、その逆も同様であるように、 でコンパイルしているようです。GCC の可視性属性を使用すると、この効果を逆転させることができます。

手短に

  • 単一のオブジェクト ファイルのエンティティ (グローバル、ローカルなど) にわたる宣言のスコープ可視性
  • 複数のオブジェクト ファイル (外部、内部) のエンティティにまたがる宣言のリンケージの可視性
  • さまざまな共有ライブラリのエンティティ間での宣言の可視性 (デフォルト、非表示)。

もう 1 つの可能性は、C と C++ のコードが混在していて、言語リンケージが台無しになっていることです。

于 2013-05-24T08:48:16.917 に答える