2

C++ では、動的ライブラリ内から外部で定義されたグローバル変数にアクセスできますか?

次のようにヘッダー ファイルで宣言されたグローバル変数があります。

ファイル名 : TestVariable.hpp

#ifndef TESTVARIABLE_HPP
#define TESTVARIABLE_HPP

extern
int   testVariable;

#endif 

次に、ソース コード ファイルで次のように定義します。

ファイル名: TestVariable.cpp

int   testVariable;

私の動的ライブラリを構成するソース コードは次のとおりです。

ファイル名 : Plugin.cpp

#include <TestVariable.hpp>

#ifdef __cplusplus
extern "C" {
#endif

void *
__attribute__((constructor))
loadLibrary
(
 void
)
{
    testVariable = 100;
}

void *
__attribute__((destructor))
unloadLibrary
(
 void
)
{
}

#ifdef __cplusplus
}
#endif

私のメイン関数は次のように定義されます。

ファイル名 : main.cpp

#include <iostream>
#include <dlfcn.h>
// dlopen
#include <TestVariable.hpp>

using std::cout;
using std::endl;

int main(void)
{
    void * libHandle_p = NULL;


    cout << "Test variable = " << testVariable << endl;

    // Load the dynamic library.

    libHandle_p = dlopen("./.libs/libPlugin.so", RTLD_LAZY);

    if (libHandle_p == NULL)
    {
        cout << "Error loading library" << endl;
        return(-1);
    }

    cout << "Test variable = " << testVariable << endl;
    return(0);
}

GNU Autotools、g++、および ld を使用して、すべてのコードを正しく (警告なしで) コンパイルおよびリンクできますが、結果のバイナリ実行可能ファイルを実行すると、動的ライブラリ ファイルを dlopen できません。しかし、関数loadLibraryの本体を構成する唯一のコード行をコメントアウトし、再コンパイルしてリンクすると、プログラムは正しく動作します!

よくわからない場合は、ライブラリ (ライブラリ) で dlopen が呼び出されたときに、ライブラリがグローバル変数testVariableへの参照を解決できず、これが dlopen 操作の失敗の原因であると言えます。リンケージタイプや名前マングリングがこの問題と関係があるのでしょうか?

生成されたダイナミック ライブラリで Linux nm ユーティリティを実行すると、シンボルtestVariableが未定義、つまり "U" であることが通知されます。バイナリ実行可能ファイルで nm ユーティリティを実行すると、シンボルtestVariableが存在し、初期化されていないデータ セクション (つまり "B") 内に存在することが通知されます。では、動的ライブラリをロードするときに dlopen がこのシンボルを解決できないのはなぜでしょうか?

ソース ファイルPlugin.cppから動的ライブラリのみを生成します。バイナリ実行可能ファイルは、2 つのソース コード ファイルmain.cppおよびTestVariable.cppから生成されています。

誰か助けてください。答えは私の顔を見つめていると断言できますが、私はそれを見ていません。

前もって感謝します。

4

1 に答える 1