<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
     "http://docbook.org/xml/4.2/docbookx.dtd">
<article lang="it">
  
  <articleinfo>
    
    <title>C++ dlopen mini HOWTO</title>
    
    <author>
      <firstname>Aaron</firstname>
      <surname>Isotton</surname>
      <affiliation>
        <address><email>aaron@isotton.com</email></address>
      </affiliation>
    </author>
    
    <pubdate>2006-03-16</pubdate>

    <revhistory>

	
      <revision>
	<revnumber>1.10</revnumber>
	<date>2006-03-16</date>
	<authorinitials>AI</authorinitials>
	
      <revremark>Cambio di licenza da GFDL a GPL. Corretta la spiegazione
	      dell'uso di dlerror, al riguardo si ringrazia Carmelo Piccione.
	      Esempio d'uso di un virtual destructor, in materia si ringrazia 
	      Joerg Knobloch. Aggiunta la sezione Sorgenti. Correzioni minori.
      </revremark>
	
      </revision>

      <revision>
	<revnumber>1.03</revnumber>
	<date>2003-08-12</date>
	<authorinitials>AI</authorinitials>
	<revremark>Inclusa menzione del Dynamic Module Loader GLib. Si ringrazia 
	G. V. Sriraam per il suggerimento.</revremark>
      </revision>
      
      <revision>
        <revnumber>1.02</revnumber>
        <date>2002-12-08</date>
        <authorinitials>AI</authorinitials>
        <revremark>Aggiunta una FAQ.  Altre modifiche minori.</revremark>
      </revision>

      <revision>
        <revnumber>1.01</revnumber>
	<date>2002-06-30</date>
        <authorinitials>AI</authorinitials>
        <revremark>Aggiornamento del materiale sui virtual destructor.
	Altre modifiche minori.</revremark>
      </revision>

      <revision>
	<revnumber>1.00</revnumber>
	<date>2002-06-19</date>
	<authorinitials>AI</authorinitials>
	<revremark>Spostato il copyright e la licenza all'inizio del documento. 
	Aggiunta la sezione riguardante i termini impiegati in questo documento.
	Altre modifiche minori.</revremark>
      </revision>
      
      <revision>
	<revnumber>0.97</revnumber>
	<date>2002-06-19</date>
	<authorinitials>JYG</authorinitials>
	<revremark>Modifiche minori riguardanti la grammatica e la struttura delle frasi.</revremark>
      </revision>

      <revision>
        <revnumber>0.96</revnumber>
        <date>2002-06-12</date>
        <authorinitials>AI</authorinitials>
        <revremark>Aggiunta la bibliografia. Corretta la spiegazione delle funzioni e 
	variabili extern.</revremark>
      </revision>

      <revision>
        <revnumber>0.95</revnumber>
        <date>2002-06-11</date>
        <authorinitials>AI</authorinitials>
        <revremark>Modifiche minori..</revremark>
      </revision>

    </revhistory>
    
    <abstract>
      <para>Come caricare dinamicamente funzioni e classi C++ per mezzo dell'interfaccia
      <function>dlopen</function>. 
      Traduzione a cura di Federico Lucifredi &lt;lucifred@fas.harvard.edu&gt;, Harvard University.</para>
    </abstract>
    
  </articleinfo>
  
  
  <section id="intro">
    <title>Introduzione</title>
    
    <para>
      Una domanda spesso posta da programmatori C++ che sviluppano sotto Unix
      riguarda il come si proceda al caricamento di funzioni e classi C++ dinamicamente
      per mezzo dell'API <function>dlopen</function>.
    </para>
    
    <para>In pratica, far ci&ograve; non &egrave; sempre semplice e qualche spiegazione in merito
    sembra dovuta - questo &egrave; l'obiettivo di questo documento.</para>
    
    <para>Una conoscenza intermedia dei linguaggi <systemitem>C</systemitem>
      e <systemitem>C++</systemitem> e dell'API <function>dlopen</function> 
      sono necessari per poter comprendere appieno il documento.</para>

    <para>La versione originale di questo documento pu&ograve; essere consultata online al seguente URL: <ulink
        url="http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/"/>.</para>
    
    <section id="copyright">
      <title>Copyright e Licenza (in originale inglese)</title>

      <para>
	  This document, <emphasis>C++ dlopen mini HOWTO</emphasis>, is
	  copyrighted (c) 2002-2006 by <emphasis>Aaron Isotton</emphasis>.
	  Permission is granted to copy, distribute and/or modify this
	  document under the terms of the GNU General Public License, Version
	  2, as published by the Free Software Foundation.
      </para>
      
    </section>
  
    <section id="disclaimer">
      <title>Liberatoria</title>
      
      <para>
        Non si pu&ograve; accettare responsabilità per i contenuti di questo documento. 
        L'uso di concetti, casi di esempio e di informazione ivi contenuti &egrave; interamente a 
        rischio dell'utente. Questo documento pu&ograve; contenere errori o informazioni inaccurate
        che possono causar danno al sistema. Si proceda con cautela, e nonostante tutto 
        ci&ograve; sia estremamente improbabile, l'autore non si assume alcuna responsabilità.
      </para>
      
      <para>
        Tutti i copyright sono mantenuti dai rispettivi proprietari, eccezion fatta per
        i casi in cui si indica diversamente.  L'uso di un termine in questo documento
        non deve essere considerato come avente effetto sulla validità di qualsiasi 
        marchio registrato. La menzione di particolari prodotti o marche non deve
        essere considerato come una indicazione di preferenza dell'autore per tal prodotto.
      </para>
    </section>
    
    <section id="credits">
      <title>Ringraziamenti a Coloro Che Hanno Contribuito</title>
      
      <para>
        In questo documento, l'autore ha il piacere di riconoscere il contributo ricevuto da (in ordine 
        strettamente alfabetico) :
      </para>
      
      <itemizedlist>

        <listitem>
          <para>Joy Y Goodreau <email>joyg (at) us.ibm.com</email> per il 
	suo lavoro di revisione editoriale.</para>
        </listitem>

        <listitem>
          <para>D. Stimitis <email>stimitis (at) idcomm.com</email>
            per aver portato all'attenzione dell'autore alcune sottigliezze
	  riguardanti il processo di decorazione dei simboli (name mangling)
	  e della clausola <literal>extern "C"</literal>.</para>
        </listitem>

	<listitem>
	<para>Numerosi altri hanno indicato errori o dato suggerimenti per
	      migliorare questo documento. Voi sapete chi siete!</para>
	</listitem>

      </itemizedlist>
      
    </section>
    
    <section id="feedback">
      <title>Commenti</title>
      
      <para>
        L'autore apprezza i commenti del lettore, che possono essere inviati al seguente
        indirizzo e-mail: <email>aaron@isotton.com</email>.
      </para>
    </section>

    <section>
      <title>Termini Usati in Questo Documento</title>

      <variablelist>
        <varlistentry>
          <term><function>dlopen</function> API</term>
          <listitem>
            <para>L'insieme delle funzioni <function>dlclose</function>,
              <function>dlerror</function>,
              <function>dlopen</function> e
              <function>dlsym</function> come descritte nella pagina
              <literal>dlopen(3)</literal> di man.</para>
            
            <para>Si osservi l'uso del termine 
              <quote><function>dlopen</function></quote> con riferimento individuale alla 
	    <emphasis>funzione</emphasis> <function>dlopen</function>, e dei termini 
              <quote><function>dlopen</function> API</quote> e interfaccia 
	    <function>dlopen</function> con riferimento all'<emphasis>intera API</emphasis>.
	  </para>
          </listitem>
        </varlistentry>
      </variablelist>

    </section>
    
  </section>

  <section id="theproblem">
    <title>Il Problema</title>

    <para>Talvolta uno sviluppatore pu&ograve; trovarsi nella posizione di dover caricare
    una libreria (ed usare le funzioni ivi contenute) a runtime; questo accade il pi&ugrave;
    delle volte quando si sta sviluppando un plug-in di qualche tipo o un programma
    disegnato con una architettura modulare.
    </para>

    <para>In C caricare una libreria &egrave; estremamente semplice (&egrave; sufficiente
    invocare le funzioni <function>dlopen</function>, <function>dlsym</function> e
    <function>dlclose</function>), mentre in C++ l'operazione &egrave; leggermente
    pi&ugrave; complessa. Le difficolt&agrave; insite nel caricare dinamicamente una libreria C++
    sono in parte dovute al processo di decorazione dei simboli di linking 
    comunemente chiamato <link linkend="mangling">name mangling</link>, ed in
    parte dovute al fatto che l'interfaccia di <function>dlopen</function> &egrave; stata
    implementata pensando in C e, conseguentemente, non offre una maniera
    appropriata di caricare classi.</para>

    <para>Prima di illustrare come si caricano dinamicamente le librerie in C++, 
    &egrave; appropriato analizzare il processo di name mangling in maggior dettaglio.
    Si continui la lettura, la spiegazione del processo di decorazione dei simboli
    &egrave; importante nel comprendere le ragioni del problema e come risolverle.</para>

    <section id="mangling">
      <title>Name Mangling</title>

      <para>In ogni programma C++ (o libreria, o object file), tutte le funzioni non
      dichiarate come static sono rappresentate nel file binario da 
      <emphasis>simboli</emphasis>. Questi simboli sono speciali stringhe di testo
      che identificano unicamente una funzione nel programma, la libreria o l'object file.
      </para>

      <para>In C il simbolo e il nome della funzione corrispondono: il simbolo della
      funzione <function>strcpy</function> &egrave; appunto 
      <computeroutput>strcpy</computeroutput>, e cos&igrave; per ogni altro simbolo.
      Questo &egrave; possibile perch&eacute; in C due funzioni non dichiarate come static 
      <emphasis>devono</emphasis> necessariamente avere nomi distinti.
      </para>

      <para>Siccome il linguaggio C++ permette l'overloading di una funzione
      (diverse versioni di una funzione avente il medesimo nome ma una differente
      lista di argomenti) ed include svariate funzionalit&agrave; non presenti in C - come classi,
      funzioni che fanno parte di dette classi, la specifica di eccezioni - non &egrave; semplicemente
      possibile impiegare il solo nome della funzione come unico simbolo. Per risolvere
      questo problema, il C++ utilizza il cosiddetto meccanismo di 
      <emphasis>name mangling</emphasis>, che trasforma il nome della funzione e
      tutte le informazioni necessarie (come il numero e la dimensione degli argomenti)
      in una stringa di testo cos&igrave; ingarbugliata che solo il compiler riesce a comprenderla.
      Il simbolo risultante per la funzione <function>foo</function> potrebbe ad esempio
      essere <computeroutput>foo@4%6^</computeroutput> - o potrebbe non
      includere nemmeno la parola <quote>foo</quote>.
      </para>

      <para>Uno dei problemi risultanti dal processo di name mangling &egrave; che lo 
      standard C++ (currently <citation>ISO14882</citation>) non definisce come
      i simboli debbano essere codificati. Di conseguenza, ogni compiler <quote>decora</quote>
      i simboli in maniera diversa, alcuni compiler hanno addirittura cambiato l'algoritmo di
      name mangling tra diverse release (famoso il caso di g++ 2.x e 3.x). Anche se aveste
      studiato i dettagli del processo di name mangling del vostro compiler (e quindi sareste
      in grado di caricare funzioni per mezzo di <function>dlsym</function>), questa 
      soluzione risulterebbe funzionare solamente con quel particolare compiler, ed il
      meccanismo potrebbe non funzionare gi&agrave; con la prossima versione del medesimo.
      </para>

    </section>

    <section>
      <title>Classi</title>

      <para>Un altro problema dell'interfaccia definita da <function>dlopen</function>
      &egrave; la limitazione inerente nel fatto che la libreria supporta solamente il caricamento di 
      <emphasis>funzioni</emphasis>. Ma in C++ una libreria spesso espone la definizione
      di classi da utilizzare nei nostri programmi. Ovviamente, per poter utilizzare queste ultime
      si deve essere in grado di istanziare le medesime, ma questo non &egrave; facilmente fattibile.
      </para>

    </section>

  </section>

  <section id="thesolution">
    <title>La Soluzione</title>

    <section id="externC">
      <title><literal>extern "C"</literal></title>
      
      <para>In C++, una keyword indica che una funzione deve impiegare la convenzione
      di linking (il termine comunemente usato &egrave; &quot;binding&quot; - N.d.T.) usata in C:
      <literal>extern "C"</literal>. Una funzione dichiarata <literal>extern "C"</literal>
      viene rappresentata da un simbolo coincidente con il nome della funzione, esattamente come
      in C. Per questa ragione, solo funzioni che non sono metodi di una classe possono 
      essere dichiarate <literal>extern "C"</literal>, e non possono essere overloaded.
      </para>

      <para>Nonostante le serie limitazioni, funzioni dichiarate <literal>extern "C"</literal>
      sono estremamente utili nel nostro scenario perch&eacute; possono essere caricate
      dinamicamente utilizzando <function>dlopen</function> esattamente come una funzione C.
      </para>

      <para>Questo <emphasis>non</emphasis> significa che una funzione dichiarata 
      come <literal>extern "C"</literal> non pu&ograve; contenere codice C++. Tale funzione &egrave;
      una funzione C++ a tutti gli effetti, che pu&ograve; utilizzare le funzionalit&agrave; del linguaggio C++
      e ricevere qualunque tipo di argomento il programmatore desideri.
      </para>

    </section>

    <section id="loadingfunctions">
      <title>Caricare Funzioni</title>

      <para>In C++ le funzioni vengono caricate <emphasis>esattamente</emphasis>
      come in C, con una chiamata a <function>dlsym</function>, ma le funzioni che
      saranno caricate devono essere qualificate con <literal>extern "C"</literal> per
      evitare che i simboli vengano decorati.
      </para>

      <example>
        <title>Caricare una Funzione</title>

        <para>main.cpp:</para>
	<programlisting><![CDATA[#include <iostream>
#include <dlfcn.h>

int main() {
    using std::cout;
    using std::cerr;

    cout << "C++ dlopen demo\n\n";

    // open the library
    cout << "Opening hello.so...\n";
    void* handle = dlopen("./hello.so", RTLD_LAZY);
    
    if (!handle) {
        cerr << "Cannot open library: " << dlerror() << '\n';
        return 1;
    }
    
    // load the symbol
    cout << "Loading symbol hello...\n";
    typedef void (*hello_t)();

    // reset errors
    dlerror();
    hello_t hello = (hello_t) dlsym(handle, "hello");
    const char *dlsym_error = dlerror();
    if (dlsym_error) {
        cerr << "Cannot load symbol 'hello': " << dlsym_error <<
            '\n';
        dlclose(handle);
        return 1;
    }
    
    // use it to do the calculation
    cout << "Calling hello...\n";
    hello();
    
    // close the library
    cout << "Closing library...\n";
    dlclose(handle);
}]]></programlisting>

        <para>hello.cpp:</para>
        <programlisting><![CDATA[#include <iostream>

extern "C" void hello() {
    std::cout << "hello" << '\n';
}
]]></programlisting>
      </example>

      <para>La funzione <function>hello</function>, definita in
        <filename>hello.cpp</filename> come <literal>extern "C"</literal>,
        viene caricata in <filename>main.cpp</filename> con la chiamata
        a <function>dlsym</function>. La funzione deve essere dichiarata come
        <literal>extern "C"</literal> perch&eacute; altrimenti non sapremmo come 
        ricostruire il simbolo corrispondente al suo nome.
      </para>

      <warning>
        <para>Esistono due versioni differenti della dichiarazione <literal>extern "C"</literal>:
        la summenzionata versione <literal>extern "C"</literal>, e la corrispondente
        <literal>extern "C" { &hellip; }</literal> con le dichiarazioni in parentesi graffe.
        La prima versione, detta inline, indica linking esterno secondo la convenzione C, mentre
        la seconda versione ha effetto solo sul linking del linguaggio. Le due dichiarazioni
        seguenti sono quindi equivalenti:
          
          <informalexample>
            <programlisting>extern "C" int foo;
extern "C" void bar();
            </programlisting>
          </informalexample>
            e
          <informalexample>
            <programlisting>extern "C" {
     extern int foo;
     extern void bar();
}</programlisting>
          </informalexample>

          Dato che non c'&egrave; differenza tra una funzione dichiarata con <literal>extern</literal>
	  ed una dichiarata senza, la differenza tra i due stili non &egrave; rilevante, purch&eacute; non si stiano
          dichiarando variabili. Se si dichiarano delle <emphasis>variabili</emphasis>, non
	  dimenticare che

	<informalexample>
            <programlisting>extern "C" int foo;</programlisting>
          </informalexample>
            e
          <informalexample>
            <programlisting>extern "C" {
    int foo;
}</programlisting>
          </informalexample>
          
	<emphasis>non</emphasis> sono la stessa cosa.</para>
        
        <para>Per ulteriori chiarimenti, si faccia riferimento a
          <citation>ISO14882</citation> 7.5, prestando particolare attenzione al
          paragrafo 7, oppure si consulti <citation>STR2000</citation>
          al paragrafo 9.2.4.</para>

        <para>Prima di far cose troppo fantasiose con variabili extern, dare una scorsa
        ai documenti elencati nella sezione <link linkend="seealso">approfondimento</link>.
        </para>

      </warning>

    </section>
    
    <section id="loadingclasses">
      <title>Caricare Classi</title>

      <para>Caricare classi &egrave; un compito pi&ugrave; complesso perch&eacute; non ci serve solo un
      puntatore a funzione, ci serve un'<emphasis>istanza</emphasis> della classe.
      </para>

      <para>Non possiamo istanziare la classe utilizzando <literal>new</literal>
      perch&eacute; la classe non &egrave; definita nell'eseguibile, e 
      perch&eacute;, in certe circostanze, non ne conosciamo nemmeno il nome.
      </para>

      <para>La soluzione &egrave; nell'usare le propriet&agrave; del polimorfismo: definiamo una 
      classe <emphasis>interfaccia</emphasis> di base con metodi dichiarati
      virtuali nell'eseguibile e una classe di <emphasis>implementazione</emphasis>
      derivata da questa nel modulo che vogliamo caricare. Solitamente la classe 
      che dichiara l'interfaccia &egrave; astratta (una classe &egrave;
      astratta se tutti i suoi metodi sono dichiarati virtuali).
      </para>

      <para>Siccome il caricamento dinamico di classi viene generalmente 
      usato per la creazione di plug-in - che devono definire una
      interfaccia chiaramente definita - si sarebbe dovuto definire una 
      classe interfaccia ed una classe di implementazione in ogni caso.
      </para>

      <para>A questo punto, si devono includere nel modulo altre due funzioni che ci 
      assistano nel caricamento, dette funzioni <emphasis>class factory</emphasis> 
      (letteralmente <quote>fabbrica di classi</quote> - N.d.T.). La prima di queste
      funzioni crea un istanza della classe e ritorna un puntatore a tale istanza, mentre
      l'altra si occupa di distruggere le classi che le vengono passate.  
      Queste due funzioni sono dichiarate <literal>extern "C"</literal>.
      </para>

      <para>Per utilizzare la classe definita nel modulo, si carichino le due funzioni factory
      per mezzo di <function>dlsym</function> esattamente come si &egrave; gi&agrave; 
      illustrato nel precedente <link linkend="loadingfunctions">esempio</link>. 
      Con questo meccanismo, si possono istanziare e distruggere tante 
      istanze della classe quante si desideri avere a disposizione.
      </para>

      <example>
        <title>Caricare una Classe</title>

        <para>In questo esempio una generica classe <classname>polygon</classname>
        dichiara l'interfaccia che la classe derivata <classname>triangle</classname> 
        a sua volta implementa.
        </para>

        <para>main.cpp:</para>
	<programlisting><![CDATA[#include "polygon.hpp"
#include <iostream>
#include <dlfcn.h>

int main() {
    using std::cout;
    using std::cerr;

    // load the triangle library
    void* triangle = dlopen("./triangle.so", RTLD_LAZY);
    if (!triangle) {
        cerr << "Cannot load library: " << dlerror() << '\n';
        return 1;
    }

    // reset errors
    dlerror();

    // load the symbols
    create_t* create_triangle = (create_t*) dlsym(triangle, "create");
    const char* dlsym_error = dlerror();
    if (dlsym_error) {
        cerr << "Cannot load symbol create: " << dlsym_error << '\n';
        return 1;
    }
    
    destroy_t* destroy_triangle = (destroy_t*) dlsym(triangle, "destroy");
    dlsym_error = dlerror();
    if (dlsym_error) {
        cerr << "Cannot load symbol destroy: " << dlsym_error << '\n';
        return 1;
    }

    // create an instance of the class
    polygon* poly = create_triangle();

    // use the class
    poly->set_side_length(7);
        cout << "The area is: " << poly->area() << '\n';

    // destroy the class
    destroy_triangle(poly);

    // unload the triangle library
    dlclose(triangle);
}]]></programlisting>

        <para>polygon.hpp:</para>
        <programlisting><![CDATA[#ifndef POLYGON_HPP
#define POLYGON_HPP

class polygon {
protected:
    double side_length_;

public:
    polygon()
        : side_length_(0) {}

    virtual ~polygon() {}

    void set_side_length(double side_length) {
        side_length_ = side_length;
    }

    virtual double area() const = 0;
};

// the types of the class factories
typedef polygon* create_t();
typedef void destroy_t(polygon*);

#endif]]></programlisting>

        <para>triangle.cpp:</para>
        <programlisting><![CDATA[#include "polygon.hpp"
#include <cmath>

class triangle : public polygon {
public:
    virtual double area() const {
        return side_length_ * side_length_ * sqrt(3) / 2;
    }
};


// the class factories

extern "C" polygon* create() {
    return new triangle;
}

extern "C" void destroy(polygon* p) {
    delete p;
}
]]></programlisting>

      </example>

      <para>Alcune osservazioni sul processo di caricamento di classi:</para>

      <itemizedlist>
        <listitem>
          <para>&Egrave; necessario definire sia una funzione factory per creare istanze della
	classe che per distruggerle: si deve evitare l'uso dell'operatore 
	<literal>delete</literal> nell'eseguibile e <emphasis>sempre</emphasis>
	affidarsi al modulo per distruggere la classe. Questo &egrave; dovuto al fatto che in
	C++ gli operatori <literal>new</literal> e <literal>delete</literal> possono essere 
	overloaded, il che pu&ograve; condurre ad una situazione in cui le chiamate a <literal>new</literal> e
	<literal>delete</literal> invocano versioni reciprocamente non corrispondenti, 
	risultando in problemi come memory leak e segmentation fault (o in assolutamente nessun
	problema in certe circostanze). Lo stesso problema pu&ograve; verificarsi se diverse
	versioni delle librerie standard vengono usate per il linking del modulo e dell'eseguibile.
	</para>
        </listitem>

        <listitem>
          <para>Il destructor della classe interfaccia deve solitamente essere virtuale.
	In rari casi questo pu&ograve; non essere necessario, ma il vantaggio che risulta dalla 
	riduzione dell'overhead &egrave; cos&igrave; ridotto da non meritare il rischio.
	</para>
          
	<para>Se la propria interfaccia di base non necessita di un destructor, se ne definisca
	comunque una non contenente istruzioni (e dichiararla <literal>virtual</literal>),
	altrimenti prima o poi si avranno problemi, posso garantirvelo. Ulteriori
	informazioni possono essere ottenute nella sezione 20 della FAQ della newsgroup
	comp.lang.c++ (<ulink url="http://www.parashift.com/c++-faq-lite/"/>).
	</para>
        </listitem>
      </itemizedlist>

    </section>
  </section>

  <section id="source">
      <title>Sorgenti</title>

      <para>Tutto il codice sorgente contenuto in questo documento &egrave; disponibile in un
	    singolo archivio: <ulink url="examples.tar.gz"/>.</para>

  </section>

  <section id="faq">
    <title>FAQ</title>
    <qandaset>
      <qandaentry>
        <question>
          <para>Sto sviluppando sotto Windows e non riesco a trovare l'header
          <filename>dlfcn.h</filename>! Qual'&egrave; il problema?</para>
        </question>
        <answer>
		<para>Il problema &egrave; che l'header <filename>dlfcn.h</filename> 
		      non esiste sotto Windows, come non esiste una interfaccia 
		      <function>dlopen</function>. Una API con funzionalit&agrave;
	similare &egrave; centrata sulla funzione <function>LoadLibrary</function>, e la maggior parte
	delle osservazioni contenute in questo documento &egrave; applicabile a questa interfaccia.
	Si faccia riferimento al sito del <ulink url="http://msdn.microsoft.com/">Microsoft Developer Network
	</ulink> per ulteriori informazioni.</para>
        </answer>
        </qandaentry>

      <qandaentry>
	<question>
	  
	  <para>Esiste un wrapper per la Windows API <function>LoadLibrary</function>
	  che riproduca l'interfaccia di <function>dlopen</function>?
	  </para>
	  
        </question>
	<answer>
	  
	  <para>Non sono a conoscenza di nessuna API del genere, ed &egrave;
	  probabile che un wrapper in grado di supportare tutte le opzioni di
	  <function>dlopen</function> non diverr&agrave; mai disponibile.
	  </para>
	
	  <para>Esistono tuttavia delle alternative: libtltdl (parte di libtool) incapsula una
	  variet&agrave; di API per il caricamento dinamico, ivi incluse <function>dlopen</function> e
	  <function>LoadLibrary</function>. Un'altra alternativa &egrave;
	  <ulink url="http://developer.gnome.org/doc/API/glib/glib-dynamic-loading-of-modules.html">
	  la funzionalit&agrave; di caricamento dinamico di moduli di Glib</ulink>. Si pu&ograve;
	  utilizzare una di queste API per garantire una miglior portabilit&agrave; tra piattaforme.
	  Io non le ho mai usate, qundi non posso dire quanto
            stabili o funzionanti queste soluzioni risultino essere.
	  </para>
	 
	  <para>Si faccia anche riferimento alla sezione 4, <quote>Dynamically
          Loaded (DL) Libraries</quote>, della <ulink 
	url="http://www.dwheeler.com/program-library">Program Library
	HOWTO</ulink> per altre tecniche per caricare librerie e istanziare classi
	indipendentemente dalla piattaforma.</para>
	
        </answer>
      </qandaentry>
    </qandaset>
  </section>

  <section id="seealso">
    <title>Approfondimento</title>

    <itemizedlist>
      <listitem>
        <para>La pagina man per la funzione <function>dlopen(3)</function> illustra lo scopo
	e l'uso dell'API <function>dlopen</function>.
        </para>
      </listitem>

      <listitem>
        <para>L'articolo <ulink url="http://www.linuxjournal.com/article.php?sid=3687">
            <citetitle>Dynamic Class Loading for C++ on Linux</citetitle></ulink> 
	  di James Norton pubblicato sul 
	  <ulink url="http://www.linuxjournal.com/">Linux Journal</ulink>.
       </para>
      </listitem>

      <listitem>
        <para>Il proprio materiale di riferimento preferito sull'uso di <literal>extern
	 "C"</literal>, ereditariet&agrave;, funzioni virtuali, <literal>new</literal>
	 e <literal>delete</literal>. L'autore raccomanda <citation>STR2000</citation>.
	 </para>
      </listitem>

      <listitem>
        <para><citation>ISO14882</citation></para>
      </listitem>

      <listitem>
        <para>La <ulink url="http://www.dwheeler.com/program-library">Program Library 
	HOWTO</ulink>, che include la maggior parte di ci&ograve; che uno 
        sviluppatore avr&agrave; mai bisogno di sapere in materia di librerie 
        statiche, condivise e caricate dinamicamente e come crearle. Altamente raccomandato.
        </para>
      </listitem>

      <listitem>
        <para>La <ulink url="http://tldp.org/HOWTO/GCC-HOWTO/index.html">Linux GCC
	HOWTO</ulink> illustra come creare librerie con GCC.
        </para>
      </listitem>

    </itemizedlist>

  </section>

  <bibliography>

    <bibliomixed>
      <abbrev>ISO14482</abbrev> <title>ISO/IEC 14482-1998 &mdash; The
        C++ Programming Language</title>. <releaseinfo>Disponibile sia in PDF 
        che rilegata in un libro <ulink url="http://webstore.ansi.org/"/>.</releaseinfo>
    </bibliomixed>

    <bibliomixed>
      <abbrev>STR2000</abbrev>
      <author><surname>Stroustrup</surname> <firstname>Bjarne</firstname></author>
      <title>The C++ Programming Language</title>, <edition>Special
        Edition</edition>.
      ISBN <isbn>0-201-70073-5</isbn>.
      <publishername>Addison-Wesley</publishername>.
    </bibliomixed>

  </bibliography>

</article>


