2013-01-21 18 views
5

(burada C-kitap gerçekten kapalı kaynak ile paylaşılan kitaplığı (libcustomer.so) uzatmak istiyorum :)Dinamik bağlantılı bir paylaşılan kitaplığı genişletir misiniz? Ben bilginin benim eksikliği için çok üzgünüm, C yeniyim

masif, ama herkese açıktır bilinen API

Böyle bir şey mümkün mü?

  1. yeniden adlandırma libcustomer.so
  2. uzatılmış paylaşılan kütüphane libcustomer.so benim genişletilmiş libcustomer.so aracılığıyla -loldcustomer içine liboldcustomer.so
  3. linki (böylece diğerleri örtülü genişletilmiş bir kullanın) oluşturmak liboldcustomer.so için

o şekilde işe yarayacağını sanmıyorum "liboldcustomer.so" eski doğrudan herhangi olmayan ekstra uygulanan yöntemler iletmek (adın öyle .bu içine değil derlenir?). Ama alternatif nedir?

# 4 için: Bunu yapmak için genel bir yol var mı, yoksa eski olana benzer bir yöntem yazmalı mıyım ve çağrıyı yönlendirmeli miyim (nasıl?)?

Orijinal libcustomer.so (= liboldcustomer.so) zaman zaman değişebileceğinden, tüm bu öğeler dinamik olarak çalışmalıdır.

Güvenlik nedeniyle

, sistemimiz hiçbir LD_PRELOAD vardır (Aksi bunu :(alacağını).

genişletilmiş doğrulama-çek & bazı iyi NPE taşıma işlemleri düşünün.

peşin Yardımlarınız için !

DÜZENLEME:

cevap gösterildiği gibi sadece benim uzantısını uygulamaya ediyorum, ama şu an bir işlenmeyen durum var

:

Genişletilmiş kitaplıktaki yapıları nasıl "proxy" yapabilirim? Örneğin

bu var:

customer.h:

struct customer; 

customer.c:

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

Şimdi benim müşteri extension.c içinde yazıyorum bütün kamu yöntemleri customer.c'yi oluşturur, ancak yapıları nasıl "geçebilirim"?

Zamanınız için çok teşekkürler & yardım!

+0

İlk ek sorunuzun cevabı zaten verilmiş. İkincisi yakından ilişkilidir - C/C++, Java/.NET gibi herhangi bir ikili metainformation içermez, bu yüzden bir 'müşteri' yapısının tanımının nasıl olabileceğini tahmin edemezsiniz. Bu yapıda alanların türlerini ve adlarını hatırlasanız bile, derleyici ayarlarında sorun olabilir - ör., Alan hizalaması. –

+0

Tamam teşekkürler. Şimdi gönderilecek cevabı deneyeceğim :) –

cevap

5

Yani bazı statik başlatma başka kütüphane oluşturma gibi görünebilir

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

adım 4 ile OldLib var.

içeriği ile NewLib oluşturun:

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 ve eski API bazı açıklama varsa hepsi func_ptr 'ın otomatik olarak oluşturulan edilebilir. NewLib oluşturulduktan sonra, OldLib'i kesinlikle değiştirebilirsiniz.

+0

Oh, bu harika! Bu yarın akşamı deneyeceğim ve sonra geri bildirim vereceğim. Çok teşekkür ederim :) –

+0

Rica ederim. Ve ben de (neredeyse) cevabı kendiniz yazdığınızı itiraf etmeliyim :) –

+0

Çok ilginç dinamik yükleme tekniği! – loretoparisi

İlgili konular