2010-12-13 19 views
0

こんにちは私は、実行時にカスタマイズしたいグローバル関数を持つプログラムを持っています。さあ、共有ライブラリには多くのバージョンの関数foo()が散在しています。さて、実行時に検出されたシステム構成に基づいて、適切なライブラリの関数を使用したいと思います。動的ライブラリの関数のオーバーライド

ファイルloader.cpp:

#include <dlfcn.h> 
#include <iostream> 

void __attribute__((weak)) foo(); 

    int main(int argc, char *argv[]) 
    { 
     void* dl = dlopen("./other.so", RTLD_NOW | RTLD_GLOBAL); 
     if (!dl) 
     { 
      std::cerr << dlerror() << std::endl; 
      return 1; 
     } 
     if (foo) 
     { 
      foo(); 
     } 
     else 
     { 
      std::cerr << "No foo?" << std::endl; 
     } 
     dlclose(dl); 
     return 0; 
    } 

ファイルother.cpp:

#include <iostream> 

void foo() 
{ 
    std::cout << "FOO!" << std::endl; 
} 

弱いシンボルがオーバーライドされていない場合しかし、私は

g++ -Wall -fPIC -o loaded loader.cpp -ldl 
g++ -Wall -fPIC -shared -o other.so other.cpp 

してプログラムをコンパイルします。何かヒント?

答えて

4

シンボルは、参照されるイメージの読み込み中に解決されます。したがって、実行可能ファイルがロードされると、fooへの参照はすでに解決されています。後のdlopenはすべてのシンボルを再バインドしません。後のロードにのみ影響する可能性があります。

あなたが代わりにdlsymを使用する必要がある、または設定LD_PRELOADます:

[email protected]:/tmp$ LD_PRELOAD=/tmp/other.so ./loaded 
FOO! 
0

あなたは++グラムと共有ライブラリをコンパイル。その結果、関数の名前がマングルされている :あなたはそれ純粋なCのコードを作成し、代わりのG ++の gccでコンパイルした場合、あなたが期待するよう

$ nm -S other.so |grep foo 
0000000000000690 000000000000002e T _Z3foov 

、あなたはそれが働いています。次のように

あるいは、それを定義:

extern "C" void foo() 
{ 
    std::cout << "FOO!" << std::endl; 
} 
関連する問題