5

私はCが初めてなので、知識が不足していて申し訳ありません(ここにある私のCブックは本当に大規模です:)

クローズド ソースで共有ライブラリ (libcustomer.so) を拡張したいと考えていますが、API は公開されています。

このようなことは可能ですか?

  1. libcustomer.so の名前を liboldcustomer.so に変更します
  2. 拡張共有ライブラリ libcustomer.so を作成します (したがって、他のユーザーは暗黙のうちに拡張ライブラリを使用します)
  3. -loldcustomer 経由で liboldcustomer.so を私の拡張 libcustomer.so にリンクします
  4. 余分に実装されていないメソッドを古い「liboldcustomer.so」に直接転送します

そのようには機能しないと思います (名前は .so にコンパイルされますよね?)。しかし、代替手段は何ですか?

#4の場合:これを行う一般的な方法はありますか、それとも古いメソッドのような名前のメソッドを作成して呼び出しを転送する必要がありますか(どのように?)?

元の libcustomer.so (=liboldcustomer.so) は時々変更される可能性があるため、すべてが動的に機能するはずです。

セキュリティ上の理由から、私たちのシステムには LD_PRELOAD がありません (それ以外の場合は :( )。

拡張された検証チェックといくつかのより良い NPE 処理について考えてみてください。

よろしくお願いします。

編集:

回答に示されているように拡張機能を実装しているだけですが、現時点では未処理のケースが 1 つあります。

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

たとえば、私はこれを持っています:

customer.h:

struct customer;

customer.c:

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

今、customer-extension.c で、customer.c からすべてのパブリック メソッドを作成していますが、構造体を「パススルー」するにはどうすればよいでしょうか。

お時間とご協力ありがとうございます。

4

1 に答える 1

5

だからあなたはOldLibを持っています

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

ステップ 4 は、静的な初期化を行う別のライブラリを作成するように見えるかもしれません。

次の内容で NewLib を作成します。

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");
   ...
}

古い API の説明があればstatic_global_init、 とすべてのを自動生成できます。func_ptrNewLib が作成されたら、OldLib を確実に置き換えることができます。

于 2013-01-21T23:12:36.850 に答える