[C] Passaggio parametri

Da JAVA a C# passando per PHP, SQL ed HTML
Avatar utente
Malo
Messaggi: 156
Iscritto il: sabato 3 dicembre 2011, 14:33

[C] Passaggio parametri

Messaggio da Malo »

Ciao a tutti sto facendo un cavolo di progetto per l'uni che mi sta facendo uscire di testa!
Allora, vi premetto che sto lavorando con le socket in C su linux (quindi non winsock per intenderci).
Ho creato due funzioni per connettersi ai vari server.

Ecco i prototipi;

Codice: Seleziona tutto

void logger_registration(char* buff, struct sockaddr *logaddr)
int server_registration(char* nomefile, struct sockaddr *ds_addr)
Così sono quando le richiamo:

Codice: Seleziona tutto

logger_registration(dati,(struct sockaddr *) &logaddr);
server_registration("indirizzoDS",(struct sockaddr *) &ds_addr);
La parte su cui focalizzarsi sono i due secondi parametri delle funzioni, che sono due puntatori a struttura, poichè questa è passata per riferimento. Ora, la suddetta struttura è "struct sockaddr_in", che contiene i vari campi .sin_addr, sin_port....cioè i due parametri logaddr e ds_addr sono di questo tipo.
Una volta passati questi parametri alla funzione dovrei essere in grado di accedere ai campi della struttura.
Invece no, e mi da il seguente errore:
Proxy.c: In function ‘logger_registration’:
Proxy.c:46:9: error: request for member ‘sin_addr’ in something not a structure or union
Proxy.c:60:9: error: request for member ‘sin_port’ in something not a structure or union
Proxy.c: In function ‘server_registration’:
Proxy.c:75:16: error: request for member ‘sin_family’ in something not a structure or union
Proxy.c:89:13: error: request for member ‘sin_addr’ in something not a structure or union
Proxy.c:95:13: error: request for member ‘sin_port’ in something not a structure or union
Come gliegli devo passare sti parametri per accedere ai campi?
Non so se sono stato molto chiaro :lol:
Ecco la mia CONFIGURAZIONE PC:

Alimentatore RASURBO Silent&Power DLP-55.1 - 550 W, CPU AMD Phenom II X4 960T, Mobo ASUSTeK M5A99X EVO, RAM 2x2GB DD3-1333 Corsair, Video ATI HD 6770, HDD Seagate barracuda SATA3 2TB, Case PowerStation Recom, Mouse logitech MX1000, Windows 7 Ultimate, Monitor Samsung LT27A300 27" LED LCD, Audio Dolby digital 5.1 logitech

Immagine

Avatar utente
Alessio89
Messaggi: 8098
Iscritto il: martedì 29 novembre 2011, 23:47

Re: [C] Passaggio parametri

Messaggio da Alessio89 »

premetto che ho studiato il C++ e non il C, ma in ogni caso le cose dovrebbero essere idenbtiche in questo caso:

nel prototipo leva via quelle "struct" in quanto il tipo di dato è specificato da "sockaddr", struct è come union e class (in c++): servono a crearti il tuo tipo di dato e come keyword in se non denotano alcun tipo di dato specifico.

pertanto sarebbe così:

Codice: Seleziona tutto

void logger_registration(char* buff, sockaddr* logaddr);
int server_registration(char* nomefile, sockaddr* ds_addr);
ricordati anche dei punti e virgola;

la chiamata alle funzioni avviene eliminando del tutto il tipo del dato, ci metti semplicemente il nome dell'identificatore.

Codice: Seleziona tutto

logger_registration(dati,  &logaddr);
server_registration("indirizzoDS", &ds_addr);
PS: stai attendo ai reference: io li uso sempre quando posso al posto dei puntatori ma ricordati che il passaggio avviene per riferimento. Se vuoi metterti un controllo di sicurezza (nonché di ulteriore incremento di performance, seppure minimo), mettici davanti una "const: in questo modo il compilatore si assicura che il dato non possa essere modificato.

Avatar utente
Malo
Messaggi: 156
Iscritto il: sabato 3 dicembre 2011, 14:33

Re: [C] Passaggio parametri

Messaggio da Malo »

Dunque innanzitutto grazie mille.
Ho provato a fare come hai detto e mi da il seguente errore:

Codice: Seleziona tutto

malo@malo-desktop ~/Scrivania/RetiLab/Progetto_Finale/Sorgenti $ make all
gcc    -c -o Proxy.o Proxy.c
Proxy.c:25:38: error: unknown type name ‘sockaddr’
Proxy.c:64:41: error: unknown type name ‘sockaddr’
make: *** [Proxy.o] Error 1
ho provato a mettere sockaddr_in ma nulla...togliendo struct non riconosce più la struttura...
Ecco la mia CONFIGURAZIONE PC:

Alimentatore RASURBO Silent&Power DLP-55.1 - 550 W, CPU AMD Phenom II X4 960T, Mobo ASUSTeK M5A99X EVO, RAM 2x2GB DD3-1333 Corsair, Video ATI HD 6770, HDD Seagate barracuda SATA3 2TB, Case PowerStation Recom, Mouse logitech MX1000, Windows 7 Ultimate, Monitor Samsung LT27A300 27" LED LCD, Audio Dolby digital 5.1 logitech

Immagine

Avatar utente
Alessio89
Messaggi: 8098
Iscritto il: martedì 29 novembre 2011, 23:47

Re: [C] Passaggio parametri

Messaggio da Alessio89 »

prova ad allegarmi il sorgente, ora non conosco la libreria che usi ma almeno vedo com'è il resto del codice

Avatar utente
conoscenza
Messaggi: 3821
Iscritto il: venerdì 2 dicembre 2011, 23:27
Località: Parma

Re: [C] Passaggio parametri

Messaggio da conoscenza »

forse dico una fesseria: definivi sockaddr drento la definizione della di funzione?
Ora togliendo "struct" all'interno della definizione della funzione, non ti viene più riconosciuta come tale.

Prova a definire le strutture esternamente alle funzioni. Compila?
Sono allergico a mele morsicate e a finestre con tende.

Segnalate qui le vostre offerte di smartphone e tablet!!!

RDA
Messaggi: 10
Iscritto il: lunedì 9 gennaio 2012, 14:42

Re: [C] Passaggio parametri

Messaggio da RDA »

Suppongo tu non abbia dimenticato di includere #include <sys/socket.h>; inoltre devi mettere struct prima di sockaddr, poiché non c'è un typedef.
Quindi, tornando al tuo sorgente originale, forse dico una banalità ma poiché hai passato un puntatore, devi usare l'operatore -> anziché il punto per i campi. Esempio logaddr->sin_addr. Se metti il punto sicuramente avrai errore in compilazione.

Avatar utente
Malo
Messaggi: 156
Iscritto il: sabato 3 dicembre 2011, 14:33

Re: [C] Passaggio parametri

Messaggio da Malo »

prova ad allegarmi il sorgente, ora non conosco la libreria che usi ma almeno vedo com'è il resto del codice
Fatto :D Dovrai perdonare i pasticci, non sono un gran scrittore di codice...
forse dico una fesseria: definivi sockaddr drento la definizione della di funzione?
Ora togliendo "struct" all'interno della definizione della funzione, non ti viene più riconosciuta come tale.

Prova a definire le strutture esternamente alle funzioni. Compila?
La sockaddr è definita in una libreria a parte che è inclusa nel sorgente, le due variabili che invoco sono di tipo sockaddr_in, quindi direi che sono già esterne alle funzioni. Ho capito giusto?
Suppongo tu non abbia dimenticato di includere #include <sys/socket.h>; inoltre devi mettere struct prima di sockaddr, poiché non c'è un typedef.
Quindi, tornando al tuo sorgente originale, forse dico una banalità ma poiché hai passato un puntatore, devi usare l'operatore -> anziché il punto per i campi. Esempio logaddr->sin_addr. Se metti il punto sicuramente avrai errore in compilazione.
No no è incluso, cioè non propriamente ma c'è...nel senso che uso una libreria che ci ha dato il prof che cmq è uguale.
Ho provato a mettere il -> e mi da un errore diverso, dice che la sockaddr non ha quei campi suddetti....

Provo a riepilogare un attimo:

Codice: Seleziona tutto

int main(int argc, char **argv)
{
  VARIABILI VARIE BLA BLA
  struct sockaddr_in ds_addr,logaddr;

 CAGATE VARIE..
 logger_registration(dati,(struct sockaddr *) &logaddr);
 server_registration("indirizzoDS",(struct sockaddr *) &ds_addr);
}
i prototipi sono invece:

Codice: Seleziona tutto

void logger_registration(char* buff, struct sockaddr *logaddr);
int server_registration(char* nomefile, struct sockaddr *ds_addr);
Non hai i permessi necessari per visualizzare i file allegati in questo messaggio.
Ecco la mia CONFIGURAZIONE PC:

Alimentatore RASURBO Silent&Power DLP-55.1 - 550 W, CPU AMD Phenom II X4 960T, Mobo ASUSTeK M5A99X EVO, RAM 2x2GB DD3-1333 Corsair, Video ATI HD 6770, HDD Seagate barracuda SATA3 2TB, Case PowerStation Recom, Mouse logitech MX1000, Windows 7 Ultimate, Monitor Samsung LT27A300 27" LED LCD, Audio Dolby digital 5.1 logitech

Immagine

Avatar utente
Alessio89
Messaggi: 8098
Iscritto il: martedì 29 novembre 2011, 23:47

Re: [C] Passaggio parametri

Messaggio da Alessio89 »

solo un consiglio, ora non leggo il sorgente visto che è tardi: impara ad dividere il lavoro su più file sorgente, mettere tutto assieme in un unico file comporta solo che confusione e complica un sacco la lettura del codice.

Avatar utente
conoscenza
Messaggi: 3821
Iscritto il: venerdì 2 dicembre 2011, 23:27
Località: Parma

Re: [C] Passaggio parametri

Messaggio da conoscenza »

Alessio89 ha scritto:solo un consiglio, ora non leggo il sorgente visto che è tardi: impara ad dividere il lavoro su più file sorgente, mettere tutto assieme in un unico file comporta solo che confusione e complica un sacco la lettura del codice.

anche io sono abituato a mettere funzione per funzione e poi richiamarle! (con lo iec-61131/3 poi è facilissimo)

Malo mi dispiace, ma è davvero da troppo tempo che non uso il C e non ricordo granchè! Vedrai che Alessio ti aiuterà!

ps: seguirò il post per ripasso! :D
Sono allergico a mele morsicate e a finestre con tende.

Segnalate qui le vostre offerte di smartphone e tablet!!!

Avatar utente
Alessio89
Messaggi: 8098
Iscritto il: martedì 29 novembre 2011, 23:47

Re: [C] Passaggio parametri

Messaggio da Alessio89 »

anzi ho dato una letta veloce ora: devi assolutamente imparare a strutturare meglio il codice, già il C è obsoleto di suo come linguaggio ma se proprio devi usarlo evita la programmazione imperativa e vai per la procedurale (ancor meglio poi compila il tutto con un compilatore C++ che anche se non permettono certe libertà che il C concede, hanno generalmente un sistema di rivelazione di errori e di warning nettamente superiore ai compilatori C e ti aiutano a scrivere pertanto un codice più pulito e semplice, pur rimanendo con le funzionalità del C... poi nessuno alla fine ti vieta di compilare il tutto col tuo compilatore preferito )

ad esempio una struct non è già definita (in un tuo sorgente o in una libreria) sarebbe bene che venisse definita da qualche parte prima di usarla come dato in un prototipo e ancor di più, altrimenti si incappa facilmente in questi errori e viene fuori un macello.

scommetto che tutti questi problemi svanirebbero facilmente se tu cambiassi stile di programmazione e soprattutto se tu iniziassi a dividere il codice su più file (uno per il main o per il test, un header da usare come interfaccia di funzioni, procedure e strutture, e un altro sorgente che contiene appunto i loro sorgenti)

ora non avendo a disposizione le tue librerie non posso provare a compilare il tutto e vedere gli errori nel dettagli, ma tu prova cmq a fare così.

UPDATE: ho visto che dichiari diverse struct nel tuo main e nei prototipi di funzione, così come nelle loro chiamate, ma non la definisci da nessuna parte.
Ora presumo che in realtà quelle struct siano già definite altrove in una delle librerie che hai incluso, tuttavia ri-dichiarando quel tipo di dato crei un conflitto di definizione.
Ora non so come risolvano la cosa i compilatori C, ma so di per certo che questo è ciò che ti crea problemi.
In C il concetto di namespace non esiste (altro motivo per non usare il C), pertanto tutto quello che includi è a livello globale (cosa pessima a causa di un'elevatissima possibilità di conflitto dei nomi).Le strutture che hai definito dovrebbero essere già accessibili una volta incluse le librerie appropriate.

Rispondi