Newsgroup: it.comp.lang.c++
Titolo: utilizzo di classe compilata in un file

Un saluto a tutti.
Premetto che non sono molto esperto di C++ (mi affascina il mondo della
programmazione, ma non ho né tempo né modo di fare pratica).
È da un po' di tempo che ho questo dubbio.
Se io creo una classe di nome ClasseProva, al cui interno c'è un metodo
MetodoProva, e poi compilo il tutto come una libreria, come faccio in
futuro a "caricare" in memoria quella classe compilata e ad eseguire il
metodo che contiene?
In pratica, mi sto domandando come si faccia ad utilizzare un driver, ad
esempio un driver per uno scanner dove l'interfaccia è ben standardizzata
(ClasseScanner) e posso avere due file, libEpsonPerfection1260 e
libEpsonPerfection1670, che implementano le rispettive classi che
derivano da ClasseScanner.
Se io voglio usare il primo scanner, e quindi il primo driver, e quindi
usare i metodi contenuti nella classe che è stata compilata nel primo
file, come faccio?
Grazie - saluti,
Marco.

Siamo al limite dell'Off-Topic, ma cerchero' di rispondere senza
scendere in dettagli platform-dependent.
Un modo di procedere e' questo: Il programma principale definisce
un'interfaccia e provvede una "Factory", una classe cioe' che crei
istanze concrete per quella interfaccia.
Ogni libreria provvede una classe concreta e un metodo per creare delle
istanze.
In fase di caricamento, la libreria puo' eseguire del codice (per
esempio se definisce una variabile globale, viene eseguito il suo
costruttore). Ogni libreria quindi, in fase di caricamento, comunica
con la Factory e gli "passa"  il metodo con cui creare i propri oggetti
concreti (passandogli, oltre al metodo anche un identificatore, per
esempio una stringa). Quando il programma chiede alla factory di
istanziare un oggetto corrispondente a quell'identificatore, la factory
usera' il metodo passatogli dalla libreria.
Esempio (molto semplificato, nessun controllo):
programma principale:
 --- 8< ---------------------------------
// interface.h
class Base { ... }; // interfaccia
// Interfaccia per creare istanze conrete
class BaseCreator {
  public:
    virtual Base* Create() = 0;
    virtual ~BaseCreator() {}
};
// factory di istanze concrete (unica factory per tutto il programma)
class Factory {
   // collezione di creatori, ognuno associato a un nome
  map<string, BaseCreator*> creators;
  void addCreator(string s, BaseCreator* c){
    creators[s] = c; // bisognerebbe controllare se c'e' gia'
  }
  // crea l'oggetto concreto tramite il creatore corrispondente
  Base *Create(name) {
     // dovremmo controllare se non c'e'
     return creators[name]->Create();
  }
};
// funzione pubblica per accedere alla Factory
Factory* GetFactory();
 ---8<-------------------------
Libreria:
 ---8<-------------------------
#include "interface.h"
class Concreta : public Base { ... }
class ConcretaCreator : public BaseCreator {
   Base *Create() {
     return new Concreta();
   }
   // nel costruttore, registra se stesso presso la factory
   ConcretaCreator(string name) {
     GetFactory()->addCreator(name,this);
   }
};
// instanziamo un creatore che, nel costruttore,
// si registra presso la factory
ConcretaCreator concreta_creator("concreta");
 ---8<-------------------------
L'esempio e' ridotto all'osso ma dovrebbe rendere l'idea.
Il programma puo' caricare delle librerie a run-time (tramite
delle funzioni di sistema, es. dlopen()) oppure le librerie
possono essere specificate esplicitamente in fase di link.
Nota comunque che ho tralasciato molti dettagl e in effetti
bisogna stare molto attenti quando si istanziano variabili
globali con costruttori non banali, in quanto non si hanno garanzie
sull'ordine in cui questi vengono eseguiti.
Fabio

 delle funzioni di sistema, es. dlopen())
ecco, questa era un'altra cosa che mi mancava, come si caricano le
librerie a run-time... :)
grazie infinite, saluti,
Marco

Prova questo (libtool--) :
http://cholm.home.cern.ch/cholm/misc/ltmm/index.html
-- 
int