2013-01-21 4 views
5

は(ここでは私のC-本は、本当に私はクローズドソースとの共有ライブラリ(libcustomer.so)を拡張したいと思います:)ダイナミックリンク共有ライブラリを拡張しますか?私は知識の私の不足のためにとても残念、Cで新たなんだ

大規模な、しかし、公開されています既知のAPI。

これは可能でしょうか?

  1. リネームlibcustomer.soは
  2. は、拡張共有ライブラリlibcustomer.so私の拡張libcustomer.so経由-loldcustomerにliboldcustomer.so
  3. リンク(そう他は暗黙的に拡張いずれかを使用)を作成するにはliboldcustomer.so
  4. 前進任意のない余分な実施方法を直接、私はそれがそのように働くだろうとは思わない

「liboldcustomer.so」旧へ(名前は.soのにコンパイルされ、それはないですか? )。 しかし、代わりに何がありますか?

#4:これを行う一般的な方法はありますか、古いものと同じ名前のメソッドを記述してコールを転送する必要がありますか?

オリジナルのlibcustomer.so(= liboldcustomer.so)は時々変更される可能性があるため、すべてのものが動的に動作するはずです。セキュリティ上の理由から

は、我々のシステムにはLD_PRELOADを持っていません。

拡張検証-チェック&いくつかのより良いNPE-取り扱いについて考えてみよう(そう私は:(がいることを取るだろう)。あなたの助けを事前に

感謝!

EDIT:

答えに示したように、私はちょうど私の拡張機能を実装していますが、私は、現時点では1未処理の場合があります。

拡張ライブラリから構造体を「プロキシ」するにはどうすればよいですか?例えば

私はこれを持っている:

customer.h:

struct customer; 

customer.c:

struct customer { 
    int children:1; 
    int age; 
    struct house *house_config; 
}; 

さて、私の顧客extension.cに私が書いているすべてのパブリックメソッドはcustomer.cを形成しますが、どのように構造体を "パススルー"するのですか?

多くのお時間をいただきありがとうございます&ヘルプ!

+0

あなたの最初の追加質問に対する回答は既に与えられています。 2番目のものは密接に関連しています.C/C++にはJava/.NETのようなバイナリメタ情報は含まれていないので、 'customer'構造の定義がどのように見えるかを推測できません。この構造体のフィールドの型と名前を覚えていても、フィールドの配置などのコンパイラ設定に問題がある可能性があります。 –

+0

ありがとうございます。私は今投稿された答えを試してみます:) –

答えて

5

だから、あなたは、いくつかの静的な初期化で別のライブラリを作成するようになります

void func1(); 
int func2(); 
... etc 

ステップ4でOLDLIBを持っています。

内容でNEWLIBを作成します:あなたは、古いAPIのいくつかの記述を持っている場合

void your_func1(); 

void (*old_func1_ptr)() = NULL; 
int (*old_func2_ptr)() = NULL; 

void func1() 
{ 
    // in case you don't have static initializers, implement lazy loading 
    if(!old_func1_ptr) 
    { 
     void* lib = dlopen("OldLibFileName.so", RTLD_NOW); 
     old_func1_ptr = dlsym(lib, "func1"); 
    } 

    old_func1_ptr(); 
} 

int func2() 
{ 
    return old_func2_ptr(); 
} 

// gcc extension, static initializer - will be called on .so's load 
// If this is not supported, then you should call this function 
// manually after loading the NewLib.so in your program. 
// If the user of OldLib.so is not _your_ program, 
// then implement lazy-loading in func1, func2 etc. - check function pointers for being NULL 
// and do the dlopen/dlsym calls there. 
__attribute__((constructor)) 
void static_global_init() 
{ 
    // use dlfcn.h 
    void* lib = dlopen("OldLibFileName.so", RTLD_NOW); 

    old_func1_ptr = dlsym(lib, "func1"); 
    ... 
} 

static_global_initし、すべてのfunc_ptrさんが自動生成されます。 NewLibが作成されたら、確実にOldLibを置き換えることができます。

+0

ああ、それは素晴らしいです!私はこれを明日の夕方に試し、フィードバックを与えます。ありがとうございます:) –

+0

よろしくお願いします。そして、私はあなた自身が(ほぼ)答えを書いていることも認めなければなりません:) –

+0

非常に興味深いダイナミックローディング手法です! – loretoparisi

関連する問題