Newsgroup: it.comp.lang.c++
Titolo: File Header Pre-linkati

Salve a tutti, espongo subito il mio problema.
Consideriamo il seguente codice C++
#include "MioHeader.h"
int main() {
return 0;
}
Assumiamo che "MioHeader.h" sia la seguente classe C++
// MioHeader.h
class MioHeader
{
  public:
   MioHeader ( int x=0 );
   ChangeCampo1 ( int x );
   void GetCampo1 ( );
  private:
   int campo1;
};
MioHeader::MioHeader ( int x )
{
  campo1=x;
}
void MioHeader::ChangeCampo1( int x )
{
  campo1=x;
}
int MioHeader::GetCampo1( )
{
 return campo1;
}
Il mio problema č:
vorrei che MioHeader.h avesse solo le dichiarazioni dei metodi (
l'interfaccia ) senza le definizioni, in modo da poter distribuire
liberamente le mie classi ma senza farne vedere il codice implementativo dei
metodi.
La soluzione dovrebbe essere un pre-linking delle definizioni dei metodi per
poi collegarle al programma principale. In sostanza penso che dovrei
distribuire un MioHeader.h e MioHeader.obj, se non sbaglio, nel primo la
parte dichiarativa e nel secondo quella implementativa.
In teoria dovrebbe essere cosě.
In pratica, come si fa?
Fabio

 }
Mi auguro di esserti stato di qualche utilità!
Ciao
Francesco

Caro Francesco,
la tua soluzione purtroppo continua a darmi gli stessi problemi di prima.
In pratica, includendo nel main il file .h il compilatore compila in obj, e
fino a qui ci siamo. Purtroppo però poi il linker non riesce a linkare
perché non trova le definizioni dei metodi. A me servirebbe poter utilizzare
direttamente il file .obj insieme col file .h: il file .h dovrebbe essere
incluso in testa al main ( e contiene le dichiarazioni dei metodi della
classe ) e il file .obj, già compilato, include, oltre che le dichiarazioni,
anche le definizioni.
Almeno penso che, in teoria, dovrebbe essere così, perché, dato che io non
voglio far vedere le definizioni di una certa classe "classe.h", l'unica
soluzione è utilizzare nel programma principale il file oggetto al posto
della classe sorgente. E siccome ho visto che in altri programmi vengono
incluse classi .h ma soltanto con la dichiarazione, la conclusione è che il
file .h serve, ma solo con la parte dichiarativa dei metodi, e serve
certamente anche il file .obj senza il quale il compilatore ( meglio forse
il linker ) non può sapere cosa fanno i metodi della classe.
Per chi ha già programmato in Pascal, si ricordano le famose UNIT dalle
quali, una volta compilate su disco, venivano creati dei file .TPU.
Eliminando le UNIT .PAS si aveva lo stesso identico risultato quando si
scriveva nel programma principale "uses crt, graph, MIAUNIT_1, MIAUNIT_2;"
con la differenza che il codice di queste units era illegibile.
L'inconveniente era però, che tutta la unit era illegibile, quindi non si
poteva accedere alla dichiarazione dei metodi ( se mi ricordo bene ).
Ti ringrazio comunque per il tuo interessamento.
Fabio

 perché non trova le definizioni dei metodi.
Per fargli trovare la definizione dei metodi devi compilare insieme il
file.cpp che contiene la main con il file.cpp che contiene l'implementazione
dei metodi.
Come fare questo dipende dal compilatore, in VC++ 6.0 fai compilare il file
con main, poi vai in Project ( barra strumenti )- Add to project - Files.. e
li inserisci il file .cpp che contiene l'implementazione delle funzioni!
Spero che ora funzioni tutto ( se usi VC++ 6.0 ).
Ciao
Francesco


Fabio

 In pratica, come si fa?
Ti rispondo per quel che riguarda il Borland C++ Compiler 5.6:
in Programma.cpp includi MioHeader.h, poi:
-> bcc32 MioHeader.cpp
Crea il file MioHeader.obj
Distribuisci MioHeader.h e MioHeader.obj
Per utilizzarli:
-> bcc32 Programma.cpp -L MioHeader.obj
Crea Programma.exe linkando con MioHeader.obj
--
Gerolamo

 In pratica, come si fa?
si fa esattamente come hai detto tu: distribuisci il .h e il .obj, poi 
l'utilizzatore deve:
1) #includere l'header
2) dire al linker di utilizzare anche il file oggetto
per il secondo punto non c'e` modo di farlo "automaticamente": dipende 
dallo specifico compilatore, ma in ogni caso ogni utente dovrebbe sapere 
come fare.
Nota finale: facendo cosi` puoi utilizzare il file oggetto solo con lo 
stesso compilatore che hai usato per compilarlo: se ad esempio compili 
il tuo .obj con Visual C++ non puoi riutilizzarlo con Borland C++.
ciao Anto
-- 
Antonio Cuni, 20 anni, studente
Brainbench C++ Master: 4.73, higher than 99% of all previous test takers.
C Language: 3.79, higher than 92% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

 metodi.
devi suddividere la tua classe in due file: +++.h; +++.cc. Dove nel primo, e
più precisamente il +++.h, vai a mettere la dichiarazione della classe,
assieme all'implementazione dei metodi che devono essere inline, mentre nel
secondo file vai ad inserire l'implementazione di tutti glia altri metodi
della classe. Poi compili il tutto, e rilasci il file +++.h ed il file
+++.obj. E qua, finisce il tuo lavoro. :-)
Questo perché, chi usa le tue classi, ha bisogno del +++.h, da includere nel
suo codice, per la definizione di quelle classi che usa, fra tutte quelle
che gli hai messo a disposizione, e del +++.obj, per poterlo linkare in fase
di link, al suo programma.
--
Ciao.
Maurizio
P.S.: eliminare _NO_SPAM per rispodere in privato

Io vi ringrazio davvero tutti,
però gira e rigira mi avete detto la stessa cosa senza andare al VERO
dunque.
Scusatemi se insisto, ma vorrei che foste più specifici.
Inizio io e continuate voi, ok?
// mioprog.cpp
#include "miaclasse.h"
int main()
{
 miaclasse mc( 1 );
 return 0;
}
//---------------------------------------
//miaclasse.h
class miaclasse{
miaclasse( int x = 0 );
};
//---------------------------------------
//miaclasse.cpp
#include "miaclasse.h"
miaclasse::miaclasse( int x )
{
  cout<<"Hai inserito il numero:"<<x;
}
//---------------------------------------
Passi col compilatore borland c++ 5.5:
1-Compilo miaclasse.cpp ==> bcc32 miaclasse.cpp
2-Compilo mioprog.cpp ==> bcc32 mioprog.cpp miaclasse.obj
E questo lo so fare.
Ma immaginate di avere un file header chiamato general.h così definito:
// general.h
#include "miaclasse1.h"
#include "miaclasse2.h"
.
.
.
#include "miaclasseN.h"
Il main lo compongo così:
// mioprog.cpp
#include "general.h"
int main ( )
{
  .
  .
  miaclasse1 mc1;
  miaclasse2 mc2;
  .
  .
}
- Considerate che i vari miaclasseX ( con numero naturale tale che X>0 )
sono spezzati in miaclasseX.h e
miaclasseX.cpp con relativo file oggetto miaclasseX.obj.
LE MIE SOLUZIONI:
-------------------------
-SOLUZIONE 1-
Devo forse creare un file general.cpp così definito?
// general.cpp
#include "general.h"
Devo compilarlo in obj?
Quando compilo il file mioprog.cpp devo fare bcc32 mioprog.cpp general.obj?
-SOLUZIONE 2-
Devo limitarmi a bcc32 mioprog.cpp miaclasse1.obj miaclasse2.obj
miaclasse3.obj ... miaclasseN.obj ?
Nel momento in cui sto scrivendo queste soluzioni non le ho ancora provate
al compilatore. Però se avete altre soluzioni già provate vi prego di
comunicarmele.
Grazie.
c:\thinkcpp\_

 miaclasse3.obj ... miaclasseN.obj ?
Questa, secondo me, č la soluzione migliore, anzi, per essere un po' piů
preciso. A questo dovresti aggiungere ancora un passo. Dopo che hai
compilato gli *.obj, linkali in un'unica libreria: libMieClassi.so (unix),
libMieClassi.dll (win),  sicuramente, la documentazione della Borland ti sa
dire come costruire una libreria statica/dinamica, una volta che hai
compilato i tuoi file. Cosě, ti basta distribuire solo la libreria, con i
relativi *.h, (che ti facilita, nella gestione delle versioni della
libreria).
Al cliente, dovrai dare:
-SOLUZIONE 1-
headers:
    miaclasse1.h
    miaclasse2.h
    miaclasse3.h
    ...
    miaclasseN.h
librerie:
    libMieClassi.so ( libMieClassi.dll, equivalente per Microsoft)
-SOLUZIONE 2-
headers:
    classi.h (un'unico file contenente le dichiarazioni di tutte le classi,
da te progettate)
librerie:
    libMieClassi.so ( libMieClassi.dll, equivalente per Microsoft)
Spero, di essere stato un po' piů chiaro.


 metodi.
cerca su Google "classi proxy"
Ciao
~~
artemis.alpeia