2013-01-21 121 views
5

我是新的C,我的知識的缺乏很抱歉(我這裏C-書真的是巨大的:)擴展動態鏈接共享庫?

我想延長與封閉源代碼的共享庫(libcustomer.so),但公衆已知的api。

是這樣的可能嗎?

  1. 命名libcustomer.so到liboldcustomer.so
  2. 創建一個擴展的共享庫libcustomer.so(以便其他人含蓄地使用擴展的一個)
  3. 鏈接liboldcustomer.so到我的擴展libcustomer.so通過-loldcustomer
  4. 直接轉發任何額外的未實現的方法到老「liboldcustomer.so」

我不認爲這會工作方式(姓名被編譯成。所以,不是嗎? )。 但是有什麼選擇?

對於#4:有沒有一個通用的方法來做到這一點,或者我必須寫一個像舊的方法,並轉發呼叫(如何?)?

因爲原始libcustomer.so(= liboldcustomer.so)可能會不時變化,所有這些東西都應該動態工作。

出於安全原因,我們的系統沒有LD_PRELOAD(否則我會採取:()。

想想擴展驗證的檢查&一些更好的NPE-handlings。

預先感謝您的幫助!

編輯:

我只是執行我的擴展如圖所示的答案,但我此刻有一個未處理的情況下:

如何從擴展庫中「代理」結構?

例如,我有這樣的:

customer.h:

struct customer; 

customer.c:現在

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

,在我的客戶extension.c我寫的所有公共方法形式爲customer.c,但我如何「傳遞」結構?

非常感謝您的時間&幫助!

+0

您的第一個附加問題的答案已經給出。第二個是密切相關的 - C/C++不包含任何二進制元信息,如Java/.NET,因此您無法猜測「客戶」結構的定義可能如何。即使您記得此結構中字段的類型和名稱,編譯器設置可能會出現問題 - 例如字段對齊。 –

+0

好的,謝謝。我現在將嘗試發佈的答案:) –

回答

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

static_global_init,如果你有舊的API的一些描述所有func_ptr的可以自動生成。在創建NewLib之後,您當然可以替換OldLib。

+0

哦,這太棒了!我明天晚上會試試這個,然後給予反饋。非常感謝你:) –

+0

不客氣。而且我還必須承認你已經(幾乎)自己寫了答案:) –

+0

非常有趣的動態加載技術! – loretoparisi