2011-01-26 20 views
5

Şu anki uygulamamıza (Unix, C++) bir eklenti mimarisi uygulamak ve Boost kütüphaneleri içindeki seçenekleri (bekleyen onay) incelemek istiyorum.Boost Plugin seçenekleri

Düzenleme: Çalışma zamanında dinamik olarak dinamik eklemek için arıyorum.

Boost.Plugin

Boost.Reflection

Boost.Extension

Ben herkesin deneyim/görüş, bu ve diğer uygulamaların ne olduğunu merak

.

+1

Önerilen çözümlerinizi, bildirmediğiniz bir sorun için gönderdiniz. İhtiyaçlarınız nelerdir? –

cevap

4

Eh: Sonra arayüz olsa o nesneyi kullanın. Biz sadece ".dll" veya ".bu" dosyaları için bir eklenti yönetici göz ve bir
onlara yük dlopen ve dll

extern "C" static plugin* create(arg_pack*); 
extern "C" static errno_t destroy(plugin*); 

tanımlanmalıdır extern "C" static fonksiyonların bir çift ile birlikte dlsym kullanılan map<string, pair< plugin*(*)(arg_pack*), errno_t(*)(plugin*)> >

yapabilirsiniz o zaman bir isim (yukarıdaki dize) dayalı bir eklenti arama ve aynı zamanda 'yapıcı' ya da 'yıkıcı'

var bkz olsun: gmodule

+0

ABI/API uyumluluğu denetimi? –

+0

@Vlad ABI -> extern "C", c tarzı manganlamayı garanti eder. API -> 'dlsym' tüm ilgili işlevleri kütüphaneden yüklemek için. Herhangi bir eksik varsa o zaman bu bir eklenti değil ve işlevler işaretçileri ve kütüphaneyi dlclose 'atmanız gerekiyor. – KitsuneYMG

+1

extern "C", manganlamayı garanti eder, ancak imzanın değiştiğini veya herhangi bir arabirim sağlayıcısının sağladığı değişikliklerin değiştiğini ve eklentinin farklı bir şey beklediğini, en iyi sonucun çökmesini beklediğini, ancak sonuçların çok dramatik olabileceğini (örneğin, alım satımından kaynaklanan kötü fiyatların) Bir şirket birkaç saniyede iflas ettiren sistem. Beklenen sözleşmenin yerine getirildiğinden emin olmak için bir dizi iyi kontrol yapılmalıdır. Bu temelde eklenti çerçevelerinin ana hedefi olmalı, sadece dlopen'i sarmakla kalmaz ... –

1

Çalışma zamanında sınıfları yükleyemezsiniz, çünkü C++ derlenmiş bir dildir ve sınıflar çalışma zamanında mevcut değildir. Nesneler (sınıf örnekleri) yapar.

Yapabilecekleriniz, paylaşılan kütüphaneleri çalışma zamanında yüklemek ve belirli bir arabirimin nesnelerini oluşturmasını sağlamaktır.

En az eklenti uygulaması, eklentinizin arabirimini ve bu arabirime sahip nesneler oluşturacak olan fabrika işlevinin arabirimini tanımlar. Paylaşılan kitaplığı çalışma zamanında yükleyeceksiniz, fabrika işlevini belirli bir adla bulacaksınız ve bir nesne oluşturmak için fabrika işlevini çağıracaksınız.

// plugin.h start 
#include <memory> 

struct PlugIn // interface 
{ 
    virtual ~PlugIn() = 0; 
    virtual void doSomething() = 0; 
}; 

extern "C" { 

typedef std::auto_ptr<PlugIn> PlugInFactoryFn(); 

// A plugin .so must export this one factory function. 
std::auto_ptr<PlugIn> createPlugIn(); 

} 
// plugin.h end 

// somewhere in you application 
#include "plugin.h" 
#include <assert.h> 
#include <dlfcn.h> 

std::auto_ptr<PlugIn> loadPlugIn(char const* filename) 
{ 
    void* so = dlopen(filename, RTLD_NOW | RTLD_LOCAL); 
    assert(so); 
    void* factory_function = dlsym(so, "createPlugIn"); 
    assert(factory_function); 
    return reinterpret_cast<PlugInFactoryFn*>(factory_function)(); 
} 

int main() 
{ 
    std::auto_ptr<PlugIn> a(loadPlugIn("a.so")); 
    std::auto_ptr<PlugIn> b(loadPlugIn("b.so")); 
    a->doSomething(); 
    b->doSomething(); 
} 
+0

Şimdi, bu POSIX olmayan platformlarda çalışmayacak, eklentinin yığınına nesne ayrıldığında ve ana uygulamalarda silindiğinde yığın sorunları olabilir. API/ABI uyumluluğundan bahsetmemek için ... –

+0

@ Vlad: Unix hakkında konuşuyoruz. –

+0

@Maxim: Yine de, eklentinin ve ana bilgisayarın ABI uyumlu (yani aynı veya uyumlu derleyici vb.) Ve API uyumlu olduğundan emin olmanız gerekir. Bu yüzden, Boost gibi bazı üst düzey şeylere ihtiyacınız var ve kovboy dlopen kullanmak .. bilirsin. –