Newsgroup: it.comp.lang.c
Titolo: compilare una libreria

Sto mettendo assieme più files per formare una libreria.
Ora però troverei utile poter definire alcune funzioni che devono essere
condivise dai moduli della libreria (e che quindi non possono essere 
static) e che però non dovrebbero essere resi disponibile all'utente 
della libreria. Come dovrei fare?
E.


Non so se ho capito la domanda...togli le firme di tali funzioni 
dall'header che l'utente include  per servirsi della tua libreria :)
Ciao, Alberto

 dall'header che l'utente include  per servirsi della tua libreria :)
Si',  OK. Ma se la libreria ha una funzione my_func, anche se non viene 
inclusa nello header, comunque il simbolo my_func è presente al momento 
del linking e potrebbe andare in conflitto con la funzione my_func 
definita dall'utente. Forse semplicemente devo utilizzare dei nomi tipo 
__mylib__my_func__ che si spera non diano conflitti...
E.

 __mylib__my_func__ che si spera non diano conflitti...
Non e` necessario.  La funzione my_func() viene ricercata nella libreria 
solo se non esiste negli oggetti linkati.  Per essere sicuri di cio` e` 
necessario che ogni oggetto della libreria includa un solo simbolo 
pubblico (anche se questo fosse una semplice variabile di tipo int) e 
che la libreria venga linkata sempre come ultimo elemento di input al 
linker.
Ciao
Giovanni
-- 
   A computer is like an air conditioner,
   it stops working when you open Windows.
   Registered Linux user #337974  < 
http://giovanni.homelinux.net/
 >


C99 7.1.3 Reserved identifiers
.....
- All identifiers that begin with an underscore and either an uppercase 
letter or another underscore are always reserved for any use.
- All identifiers that begin with an underscore are always reserved for 
use as identifiers with file scope in both the ordinary and tag name spaces.
.....
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com

 linker.
...quindi (se ho capito bene), una volta che sei riuscito a farla franca 
con il compilatore e il linker, anche le funzioni di libreria che 
richiamano la propria my_func(), in pratica utilizzeranno la nuova 
my_func() definita dell'utente?
Ciao



Si se un'altra funzione di libreria deve linkare my_func() viene usata 
quella dell'utente se e` gia definita.  Tutti i linker che ho usato 
funzionano in questo modo.


 funzionano in questo modo.
Si', lo so che in genere funzionano in questo modo (e che, con il trick 
che hai spiegato, probabilmente i compilatori neanche ti avvertono del 
conflitto)
Forse lo sapeva anche l'OP: e infatti aveva richiesto un metodo "per 
evitare" simili situazioni.


 potrebbe essere un'alternativa...
Ok grazie.
Ma insomma quallo che un po mi rattrista e' che dunque nel fare una 
libreria sarebbe meglio (come risultato) fare un unico grosso file 
sorgente in cui si dichiarano static tutte le funzioni che non devono 
essere rese disponibili all'utente. In questo modo nel file risultante 
libmylib.a ci saranno solamente i simboli che l'utente puo' 
effettivamente usare.
E.

?manu* ha scritto:

1) Perche' parli di libreria e non di modulo?
In un modulo si e' soliti raggruppare funzioni che, tra di loro, hanno 
una certa coesione. In una libreria no. Una libreria puo' raggruppare, 
persino per pura convenienza, diversi moduli (.o/.obj) anche di tipo 
molto eterogeneo tra loro (eg. pensa alla libc.a del gcc).
2) Non capisco le ragioni della tua conclusione.
Facciamo un esempio.
Mettiamo che tu voglia scrivere il modulo 'stdio' - quello della 
libreria standard (ovviamente e' solo un esempio).
Se ho capito bene, la domanda che ti poni sostanzialmente e' questa:
(A) meglio scrivere tutte le funzioni in un singolo modulo (stdio.c => 
stdio.o)?
(B) oppure e' meglio dividere le singole funzioni in piu' files (in 
questo caso mi resta difficile chiamarli 'moduli') - eg. printf.c => 
printf.o, fopen.c => fopen.o, ecc...?
Qui, ragionando in termini esclusivamente logici, ti risponderei subito 
di usare la soluzione (A): in primo luogo perche' tutte le funzioni 
della stdio hanno uno stretto legame tra di loro; in secondo luogo 
perche', in fase d'implementazione, sara' piu' semplice definire - e 
nascondere - tipi, variabili e funzioni ad uso strettamente 'privato'.
Ma anche la soluzione (B) ha un senso [1]: l'ottimizzazione; cioe', la 
riduzione, in termini di dimensione, del programma eseguibile che fa uso 
delle funzioni del tuo modulo. Se, per esempio, il tuo programma 
richiamasse solo una "printf", nel caso della soluzione (A) l'eseguibile 
prodotto si portera' dietro *tutto* il codice oggetto della stdio.o 
(sarebbe invece sufficiente quello relativo alla sola printf).
Per contro, usando la soluzione (B), se tutte le funzioni della tua 
stdio richiamassero (eg.) anche una sola funzione comune (e, in pratica, 
'privata') di inizializzazione, questa la dovresti - per forza - 
dichiarare 'extern'.
PS: scusa la fretta con cui ho scritto: se non sono stato chiaro dimmelo...
Note:
[1] la stdio e' normalmente implementata cosi'.
Ciao


 delle funzioni del tuo modulo. 
Infatti, questo sarebbe il modo giusto di procedere, ed e' quello che ho 
fatto.
E.

?manu* ha scritto:

...ma non sempre e' vero o e' conveniente. Dipende dai moduli.
