Il linguaggio di programmazione C
 

Passaggio di parametri ad una shared library

arkkimede 29 Ott 2015 16:18
Ciao a tutti: avrei bisogno di un po' di aiuto.
Sono alle prese con una libreria Open Source che sto cercando di modificare
leggermente.

Detta libreria e' discretamente complicata per le mie conoscenze di
programmazione (usa il cmake per inizializzare il tutto e poi tramite make
compila tutto, generando prima una lib.so e poi questa stessa e' utilizzata per
generare degli esempi messi a disposizione dagli autori.

Io sto cercando di modificare una di questi esempi ed avrei la necessita' di
passare un parametro dal main ad una di queste funzioni che poi costituiranno la
lib.so

Ho tentato di usare una variabile dichiarata fuori dal main e facendo
riferimento alla stessa nella funzione di mio interesse precedendola con extern
ma la cosa non funziona: durante la compilazione, l'errore e' relativo al fatto
che non esiste alcun riferimento alla variabile dichiarata extern.

Potreste aiutarmi?
Magari indirizzandomi verso un esempio (se non e' chiedere troppo)
Comunque grazie
fmassei@gmail.com 29 Ott 2015 16:34
On Thursday, October 29, 2015 at 4:18:14 PM UTC+1, arkkimede wrote:
> Ciao a tutti: avrei bisogno di un po' di aiuto.
> Sono alle prese con una libreria Open Source che sto cercando di
> modificare leggermente.
>
> Detta libreria e' discretamente complicata per le mie conoscenze di
> programmazione (usa il cmake per inizializzare il tutto e poi tramite
> make compila tutto, generando prima una lib.so e poi questa stessa e'
> utilizzata per generare degli esempi messi a disposizione dagli autori.
>
> Io sto cercando di modificare una di questi esempi ed avrei la necessita'
> di passare un parametro dal main ad una di queste funzioni che poi
> costituiranno la lib.so
>
> Ho tentato di usare una variabile dichiarata fuori dal main e facendo
> riferimento alla stessa nella funzione di mio interesse precedendola con
> extern ma la cosa non funziona: durante la compilazione, l'errore e'
> relativo al fatto che non esiste alcun riferimento alla variabile
> dichiarata extern.
>
> Potreste aiutarmi?
> Magari indirizzandomi verso un esempio (se non e' chiedere troppo)
>

Non credo d'aver capito che devi fare - link della lib e cosa vuoi fare? :)

Ciao!
arkkimede 29 Ott 2015 17:13
>
> Non credo d'aver capito che devi fare - link della lib e cosa vuoi fare? :)
>
> Ciao!

Immagina di avere Fun1, Fun2 e Fun3 che fatto la tua libreria shared (lib.so)

Poi hai un main che fa riferimento a p. esempio Fun1.

Fai il link del main con lib.so attieni un eseguibile e gira.


Adesso immagina di voler passare un parametro dal main a Fun1, "senza modificare
il prototipo di Fun1": c'e' qualche possibilita'?
Essendo la libreira shared crea dei problemi per il passaggio di parametri,
tramite p.es ******* h?
La strada tradizionale (dichiarata in Fun1 extern e dichiararla fuori dal main
non funziona.
Spero di essere stato piu' chiaro
Grazie comunque
Giacomo Degli Esposti 29 Ott 2015 17:17
On Thursday, October 29, 2015 at 4:18:14 PM UTC+1, arkkimede wrote:
> Ciao a tutti: avrei bisogno di un po' di aiuto.
> Sono alle prese con una libreria Open Source che sto cercando di modificare
leggermente.
>
> Detta libreria e' discretamente complicata per le mie conoscenze di
programmazione (usa il cmake per inizializzare il tutto e poi tramite make
compila tutto, generando prima una lib.so e poi questa stessa e' utilizzata per
generare degli esempi messi a disposizione dagli autori.
>
> Io sto cercando di modificare una di questi esempi ed avrei la necessita' di
passare un parametro dal main ad una di queste funzioni che poi costituiranno la
lib.so
>
> Ho tentato di usare una variabile dichiarata fuori dal main e facendo
riferimento alla stessa nella funzione di mio interesse precedendola con extern
ma la cosa non funziona: durante la compilazione, l'errore e' relativo al fatto
che non esiste alcun riferimento alla variabile dichiarata extern.
>
> Potreste aiutarmi?
> Magari indirizzandomi verso un esempio (se non e' chiedere troppo)
> Comunque grazie

Non sono sicuro di aver capito cosa stai cercando di fare, ma
credo che il tuo problema sia questo:
stai modificando la libreria introducendo una dipendenza da
un oggetto che e' definito in un sorgente che e'
all'esterno della libreria stessa perche' lo hai definito
dentro al main che poi chiamera' la libreria.
Questo e' proprio un errore logico: la libreria non puo'
dipendere dal main, casomai e' il contrario.

Per ottenere quello che vuoi devi aggiungere un parametro
in piu' alla funzione che ti serve.

ciao
Giacomo
fmassei@gmail.com 29 Ott 2015 17:21
On Thursday, October 29, 2015 at 5:13:04 PM UTC+1, arkkimede wrote:
>>
>> Non credo d'aver capito che devi fare - link della lib e cosa vuoi fare? :)
>>
>> Ciao!
>
> Immagina di avere Fun1, Fun2 e Fun3 che fatto la tua libreria shared (lib.so)
> Poi hai un main che fa riferimento a p. esempio Fun1.
> Fai il link del main con lib.so attieni un eseguibile e gira.
>

Ok.

>
> Adesso immagina di voler passare un parametro dal main a Fun1, "senza
> modificare il prototipo di Fun1": c'e' qualche possibilita'?
>

Perché vuoi fare una cosa del genere? Se già modifichi Fun1 per farle
capire il nuovo parametro, puoi modificare anche la firma. Se non vuoi
rompere la compatibilità con altri applicativi che usano lib.so, fai una
altra funzione che richiama Fun1, e dal tuo main chiami quella.

Ciao!
fmassei@gmail.com 29 Ott 2015 17:25
On Thursday, October 29, 2015 at 5:17:22 PM UTC+1, Giacomo Degli Esposti wrote:
> stai modificando la libreria introducendo una dipendenza da
> un oggetto che e' definito in un sorgente che e'
> all'esterno della libreria stessa perche' lo hai definito
> dentro al main che poi chiamera' la libreria.
> Questo e' proprio un errore logico: la libreria non puo'
> dipendere dal main, casomai e' il contrario.
>

E' un errore logico ma su linux si può fare, si mette la variabile extern
nell'applicazione si compila la shared (-fpic, -shared) e l'eseguibile con
-rdynamic.

Inutile dire che, per quello che vuole fare l'OP, sarebbe una *****ata da
evitare a tutti i costi.

Modificare la firma o fare un'altra funzione è sicuramente l'opzione più
sensata-

Ciao!
Giacomo Degli Esposti 29 Ott 2015 17:30
On Thursday, October 29, 2015 at 5:25:19 PM UTC+1, fma...@gmail.com wrote:
> On Thursday, October 29, 2015 at 5:17:22 PM UTC+1, Giacomo Degli Esposti
wrote:
>> stai modificando la libreria introducendo una dipendenza da
>> un oggetto che e' definito in un sorgente che e'
>> all'esterno della libreria stessa perche' lo hai definito
>> dentro al main che poi chiamera' la libreria.
>> Questo e' proprio un errore logico: la libreria non puo'
>> dipendere dal main, casomai e' il contrario.
>>
>
> E' un errore logico ma su linux si può fare, si mette la variabile extern
> nell'applicazione si compila la shared (-fpic, -shared) e l'eseguibile con
> -rdynamic.

Non lo sapevo... Una bella *****ata non c'e' che dire! :-D

> Inutile dire che, per quello che vuole fare l'OP, sarebbe una *****ata da
> evitare a tutti i costi.
>
> Modificare la firma o fare un'altra funzione è sicuramente l'opzione più
> sensata-

Se le funzioni wrapper sono tante e/o il parametro e' preferibile
che sia da specificare una volta sola invece che ad ogni chiamata
ce' anche questa alternativa che e'
un po' meno *****ata della variabile extern: aggiungere il paramtro
come variabile globale NELLA libreria assieme a due funzioni per
impostarla e leggerla.
In questo mdo puo' anche cambiare tutte le Fun1, Fun2, .. Fun_n della
libreria in modo da usare il nuovo parametro senza dover creare
altrettanti wrapper con il parametro in piu.

ciao
Giacomo
fmassei@gmail.com 29 Ott 2015 17:36
On Thursday, October 29, 2015 at 5:30:25 PM UTC+1, Giacomo Degli Esposti wrote:
> On Thursday, October 29, 2015 at 5:25:19 PM UTC+1, fma...@gmail.com wrote:
>> Modificare la firma o fare un'altra funzione è sicuramente l'opzione più
>> sensata-
>
> Se le funzioni wrapper sono tante e/o il parametro e' preferibile
> che sia da specificare una volta sola invece che ad ogni chiamata
> ce' anche questa alternativa che e'
> un po' meno *****ata della variabile extern: aggiungere il paramtro
> come variabile globale NELLA libreria assieme a due funzioni per
> impostarla e leggerla.
> In questo mdo puo' anche cambiare tutte le Fun1, Fun2, .. Fun_n della
> libreria in modo da usare il nuovo parametro senza dover creare
> altrettanti wrapper con il parametro in piu.
>

Eh, pure questa soluzione mi sembra buona :)

Certo, per parlare d'eleganza o *****ate bisognerebbe vedere il caso
specifico, altrimenti così andiamo un po' a caso :)

Ciao!
enoquick 29 Ott 2015 19:19
Il 29/10/2015 09:18, arkkimede ha scritto:
> Ciao a tutti: avrei bisogno di un po' di aiuto.
> Sono alle prese con una libreria Open Source che sto cercando di modificare
leggermente.
>
> Detta libreria e' discretamente complicata per le mie conoscenze di
programmazione (usa il cmake per inizializzare il tutto e poi tramite make
compila tutto, generando prima una lib.so e poi questa stessa e' utilizzata per
generare degli esempi messi a disposizione dagli autori.
>
> Io sto cercando di modificare una di questi esempi ed avrei la necessita' di
passare un parametro dal main ad una di queste funzioni che poi costituiranno la
lib.so
>
> Ho tentato di usare una variabile dichiarata fuori dal main e facendo
riferimento alla stessa nella funzione di mio interesse precedendola con extern
ma la cosa non funziona: durante la compilazione, l'errore e' relativo al fatto
che non esiste alcun riferimento alla variabile dichiarata extern.
>
> Potreste aiutarmi?
> Magari indirizzandomi verso un esempio (se non e' chiedere troppo)
> Comunque grazie
>

La soluzione migliore ti è gia stata spiegata da altri
Una' altra soluzione è che se la libreria ha come input una struct
sarebbe possibile aggiungere a questa struct un ulteriore campo.
Dal punto di vista logico se il campo da aggiungere è logicamente
correlato con la struct.
enoquick 29 Ott 2015 19:23
Il 29/10/2015 09:18, arkkimede ha scritto:
> Ciao a tutti: avrei bisogno di un po' di aiuto.
> Sono alle prese con una libreria Open Source che sto cercando di modificare
leggermente.
>
> Detta libreria e' discretamente complicata per le mie conoscenze di
programmazione (usa il cmake per inizializzare il tutto e poi tramite make
compila tutto, generando prima una lib.so e poi questa stessa e' utilizzata per
generare degli esempi messi a disposizione dagli autori.
>
> Io sto cercando di modificare una di questi esempi ed avrei la necessita' di
passare un parametro dal main ad una di queste funzioni che poi costituiranno la
lib.so
>
> Ho tentato di usare una variabile dichiarata fuori dal main e facendo
riferimento alla stessa nella funzione di mio interesse precedendola con extern
ma la cosa non funziona: durante la compilazione, l'errore e' relativo al fatto
che non esiste alcun riferimento alla variabile dichiarata extern.
>
> Potreste aiutarmi?
> Magari indirizzandomi verso un esempio (se non e' chiedere troppo)
> Comunque grazie
>

Un altra soluzione: aggiungi ... come parametro alla func e tratti la
funzione come una variable parameter list mantenendo la compatibilità
(se serve) con il regresso.
Non è una soluzione elegante ma si puo fare.
fmassei@gmail.com 29 Ott 2015 19:48
On Thursday, October 29, 2015 at 7:19:44 PM UTC+1, enoquick wrote:
> La soluzione migliore ti è gia stata spiegata da altri
> Una' altra soluzione è che se la libreria ha come input una struct
> sarebbe possibile aggiungere a questa struct un ulteriore campo.
> Dal punto di vista logico se il campo da aggiungere è logicamente
> correlato con la struct.

:)

Visto che le stiamo dicendo tutte io aggiungo! :D

Molte librerie hanno una funzione di inizializzazione che prende dei flags
(ad esempio le SDL hanno SDL_Init() che prende un uint32 dove si mettono
in or i flags relativi ai subsystems che si vogliono controllare).
In questo caso non serve neppure nessuna modifica all'interfaccia esterna:
basta aggiungere una #define! :)

Ciao!


P.S. Comunque, per dire, se l'OP ci diceva che libreria era magari davamo
un consiglio di stile migliore ;)
arkkimede 30 Ott 2015 00:38
>
> P.S. Comunque, per dire, se l'OP ci diceva che libreria era magari davamo
> un consiglio di stile migliore ;)

L'OP vi dice di che libreria si tratta: https://github.com/srsLTE/srsLTE.
Si tratta di una libreria che si interfaccia con una piastra Software Define
Ra***** ed implementa un ricevitore LTE.
La piastra è una Ettus B210 http://www.ettus.com/product/details/UB210-KIT
che implementa sostanzialmente un capionamento ad una frequenza che può andare
da 9.2MHz fino a svariate decine di MHz (circa 30), a seconda della banda della
cella che si esamina e questi campioni vengono passati via usb3 al pc con Ubuntu
che li elabora (la libreria) per estrarre informazioni relative alle celle LTE
in aria.

Per motivi su cui non mi dilungo, ho dovuto modificare detta libreria in modo
che invece di processare i campioni ottenuti dalla B201, usasse i campioni che
la medesima piastra aveva ricevuto e salvato su di un ******* binario.

I parametri che volevo passare erano relativi a come il ******* dati era stato
campionato in modo da impostare le grandezze che non posso ricavare
automaticamente come avrebbe fatto la piastra.

Osservando l'albero delle directory della libreria vedrete che c'è la directory
che si chiama srslte e sotto ci sono le directory lib, include ed examples.
In lib c'è appunto tutto il codice che genera la lib.so e dentro examples ci
sono degli esempi (di cui io ne ho modificato uno) che usano la lib.so.

Eccovi accontentati
fmassei@gmail.com 30 Ott 2015 12:19
On Friday, October 30, 2015 at 12:38:14 AM UTC+1, arkkimede wrote:
>>
>> P.S. Comunque, per dire, se l'OP ci diceva che libreria era magari davamo
>> un consiglio di stile migliore ;)
>
> L'OP vi dice di che libreria si tratta: https://github.com/srsLTE/srsLTE.
> Si tratta di una libreria che si interfaccia con una piastra Software
> Define Ra***** ed implementa un ricevitore LTE.
> La piastra è una Ettus B210 http://www.ettus.com/product/details/UB210-KIT
> che implementa sostanzialmente un capionamento ad una frequenza che può
> andare da 9.2MHz fino a svariate decine di MHz (circa 30), a seconda della
> banda della cella che si esamina e questi campioni vengono passati via
> usb3 al pc con Ubuntu che li elabora (la libreria) per estrarre
> informazioni relative alle celle LTE in aria.
>
> Per motivi su cui non mi dilungo, ho dovuto modificare detta libreria in
> modo che invece di processare i campioni ottenuti dalla B201, usasse i
> campioni che la medesima piastra aveva ricevuto e salvato su di un
> ******* binario.
>
> I parametri che volevo passare erano relativi a come il ******* dati era
> stato campionato in modo da impostare le grandezze che non posso ricavare
> automaticamente come avrebbe fatto la piastra.
>
> Osservando l'albero delle directory della libreria vedrete che c'è la
> directory che si chiama srslte e sotto ci sono le directory lib, include
> ed examples.
> In lib c'è appunto tutto il codice che genera la lib.so e dentro examples
> ci sono degli esempi (di cui io ne ho modificato uno) che usano la lib.so.
>
> Eccovi accontentati

Oh, ora è più chiaro! :)

La lib non la conoscevo, ho dato solo un'occhiata al volo ma credo d'essermi
fatto un'idea.

Per fare la cosa pulita, come prima cosa dovresti decidere (o, se vuoi fare
una patch, chiedere ad uno degli sviluppatori), se ha senso mascherare questa
funzionalità sotto una funzione che fa, di base, un altro lavoro, oppure
creare un nuovo modulo con delle funzioni dedicate. Immagino dipenda dai
casi d'uso, per cui non ti posso dare alcun parere in merito.

Altrimenti, se non t'interessa una roba pulita, tra tutti i suggerimenti
che ti sono stati dati, non essendoci né funzioni d'inizializzazione
globali, né strutture con settaggi generali, ed essendo le funzioni che
richiami molto specifiche, io andrei per il suggerimento di aggiungere
una funzione extra: puoi sia continuare a usare la lib nei casi "standard"
sia usare la nuova funzionalità su richiesta e mantieni la compatibilità
con altri applicativi installati.

M2C,
Ciao!
arkkimede 30 Ott 2015 13:28
> Oh, ora è più chiaro! :)
>
> La lib non la conoscevo, ho dato solo un'occhiata al volo ma credo d'essermi
> fatto un'idea.
>
> Per fare la cosa pulita, come prima cosa dovresti decidere (o, se vuoi fare
> una patch, chiedere ad uno degli sviluppatori), se ha senso mascherare questa
> funzionalità sotto una funzione che fa, di base, un altro lavoro, oppure
> creare un nuovo modulo con delle funzioni dedicate. Immagino dipenda dai
> casi d'uso, per cui non ti posso dare alcun parere in merito.
>
> Altrimenti, se non t'interessa una roba pulita, tra tutti i suggerimenti
> che ti sono stati dati, non essendoci né funzioni d'inizializzazione
> globali, né strutture con settaggi generali, ed essendo le funzioni che
> richiami molto specifiche, io andrei per il suggerimento di aggiungere
> una funzione extra: puoi sia continuare a usare la lib nei casi "standard"
> sia usare la nuova funzionalità su richiesta e mantieni la compatibilità
> con altri applicativi installati.
>
> M2C,
> Ciao!

Tentero' il suggerimento di Giacomo Degli Esposti.
Nei ******* .c che contengono le funzioni a cui devo passare i parametri
aggiungero' delle funzioni setParameter1, setParameter2, getParameter1,
getParameter2, etc. (ovviamente dichiarandoli nei corrispondenti .h) ed a questo
punto le funzioni dovrebbero essere visibili ovunque, anche dal main o dove mi
serve.
Posso farlo "agilmente" (almeno lo spero) perche' ogni ******* contiene piu'
funzioni ed il cmake penso faccia riferimento ai ******* e non alle funzioni.
Sarebbe stato piu' elaborato se ogni funzione era un singolo *******

Grazie comunque a tutti.
arkkimede 30 Ott 2015 15:17
Riporto "meglio" a futura memoria.

1. In un ******* (appartenente alla libreira) contenente una funzione a cui
voglio passare un parametro, all'inizio, subito dopo gli include, dichiaro una
variabile
uguale al parametro che voglio passare. La dichiaro static anche in modo da
ritrovarla gia' inizializzata quando ritorno nelle funzioni contenute in questo
******* A titolo di esempio

static int overSampling:

2. Nel medesimo ******* dichiaro una nuova funzione che imposta questa variabile
void set_overSampling(int over)
{
overSampling = over;
}

3. Nel ******* corrispondente .h riporto il prototipo di questa funzione.

4. Nel main includo il .h modificato e ove ritengo necessario scrivo p.es.
set_overSampling(8);

A questo punto la varibile globale overSampling e' stata inizializzata e
nelle funzioni contenute nel ******* .c modificato, posso usarla
tranquillamente.

Links
Giochi online
Dizionario sinonimi
Leggi e codici
Ricette
Testi
Webmatica
Hosting gratis
   
 

Il linguaggio di programmazione C | Tutti i gruppi | it.comp.lang.c | Notizie e discussioni lang c | Lang c Mobile | Servizio di consultazione news.