Pages: [1]   Go Down
Author Topic: Passaggio di argomenti ad una funzione  (Read 1406 times)
0 Members and 1 Guest are viewing this topic.
Selvazzano Dentro - Padova
Offline Offline
Edison Member
*
Karma: 45
Posts: 1504
"Chi sa fa, chi non sa insegna"
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Probabilmente per un esperto è una sciocchezza, ma non ho capito bene come passare gli argomenti ad una funzione.

Mi spiego meglio: dovrei passare una variabile ad una funzione, senza conoscere a priori che tipo è (byte, int, long, float, char, String).

La funzione lavora sulla rappresentazione della variabile in memoria, cioé sul puntatore della stessa.

Ho provato, ma ovviamente mi da un errore in compilazione sulla riga di invocazione.

Dove sbaglio?

Code:
  long Long = 250000;


  EEPROMVarSave(0x0400, Long);
...
void EEPROMVarSave(unsigned long Address, int *Var) {

  byte WBuffer;
  byte Size = sizeof(Var);

  for (byte I = 0; I < Size; I ++) {
    WBuffer = *((byte*)&Var + I);
    EEPROM.write(Address + I, WBuffer);
  }
}

« Last Edit: August 04, 2012, 01:20:02 pm by cyberhs » Logged

Offline Offline
Jr. Member
**
Karma: 2
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

è tardi quindi magari non sto pensando correttamente...ma se ricordo bene il puntatore deve essere dello stesso tipo della variabile puntata (pensando al motivo mi viene in mente il fatto che quando vai a dereferenziare il puntatore deve sapere quanti byte leggere tipo int 4 byte oppure long 8 byte...<-- ragionamento fatto ora non so quanto possa essere valido)
quindi in questo caso ti dà errore per 2 motivi, il primo è che la variabile è long, e l'altro è perchè in realtà non stai passando alla funzione un puntatore ma una variabile per passare un puntatore hai 2 modi o fai una variabile puntatore che punta a Long di questo tipo
Code:
int* punt = Long;
e poi alla funzione passi punt e non Long, oppure altro metodo che ha lo stesso risultato è usare i riferimenti mettendo una & davanti alla variabile che passi e quindi diventa &Long  (i riferimenti sono un altro modo di dire "l'indirizzo di Long")
Logged

Cagliari, Italy
Online Online
Tesla Member
***
Karma: 114
Posts: 7191
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Se non erro non è possibile passare un parametro ad una funzione senza stabilirne il tipo.
Pero puoi crearti tante funzioni identiche che accettino in ingresso tipi diversi, è poi il compilatore che in base al tipo decide quale funzione usare.

void Stampa(char input)....
void Stampa(int input)...
void Stampa(char input)...

--> http://it.wikipedia.org/wiki/Overloading
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Selvazzano Dentro - Padova
Offline Offline
Edison Member
*
Karma: 45
Posts: 1504
"Chi sa fa, chi non sa insegna"
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Per Ale92

Grazie della risposta... assonnata! :-)

Per PaoloP:

hum... questi spiegherebbe perché la funzione print(x) della Serial è composta in realtà da tante funzioni quante sono le possibi tipologie di variabile.

Però mi sembra proprio incredibile che non si possa...
Logged

Offline Offline
God Member
*****
Karma: 9
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hai diverse strade:
-gli passi DUE argomenti: il primo,è un puntatore a void,nel secondo specifichi il tipo di argomento,usando Xes un'enumerazione(se gli passi 1,intendi int,2=stringa....)..quando richiami la funzione,scrivi per esempio   funzionePippo((void*)nomeVariabile,1)..all'interno della variabile,avrai uno switch case per tutti i possibili tipi di dato su v+cui vuoi lavorare...
-usi i template di c++
-usi binding dinamico,ma ho i miei dubbi sul fatto che l'arduino lo regga,mentre le prime due strade possono essere mooolto efficienti se implementate bene..

poi ci sono molte altre strade,che posso elencarti,ma con una delle prime due dovresti cavartela egregiamente..
tieni comunque conto che la funzione chiamata dovrà conoscere il tipo,o quando viene compliata,o quando viene richiamata..
Logged

Selvazzano Dentro - Padova
Offline Offline
Edison Member
*
Karma: 45
Posts: 1504
"Chi sa fa, chi non sa insegna"
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Caro m_ri,

tu parti dal presupposto che io conosca bene il C, ma purtroppo non è cosi. :-(

Potresti gentilmente modificare la routine che ho postato all'inizio e che funziona ma che non riesco a richiamare?

Grazie infinite!

Ettore Massimo Albani
Logged

Offline Offline
God Member
*****
Karma: 9
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

vabbò,col primo metodo:

Code:
enum{ intero,stringa}tipoArg;

void EEPROMVarSave(unsigned long Address, void *Var,tipoArg tipo) {

switch(tipo){
case intero:
  byte WBuffer;
  byte Size = sizeof(Var);

  for (byte I = 0; I < Size; I ++) {
    WBuffer = *((byte*)&Var + I);
    EEPROM.write(Address + I, WBuffer);
break;
case stringa:
for (byte I = 0;; I ++) {
    WBuffer = *((byte*)(Var + I));
    EEPROM.write(Address + I, WBuffer);
    if(WBuffer==0)break;//esco dal ciclo dopo aver salvato il carattere 0
  }
break;
}
}
probab ci sono errori di sintassi..
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Questo e' con i template, a mio parere la scelta migliore nel tuo caso ( Arduino ci va a nozze e tu non ti devi sbattere sul codice smiley-wink ):
Code:
void EPROOM_write( unsigned addr , void* buff , unsigne length )
{
unsigned i;
while( length - i++ ) EPROOM.write( ((unsigned char*)addr) + i , buff[i] );
}

template <class type> void EPROOM_write( unsigned addr , type var )
{
EEPROM.write( addr , &var , sizeof(type) );
}

void EPROOM_write( unsigned addr , const char* str )
{
do EEPROM.write( addr++ , *str ); while( *str++ ); // oppure EEPROM.write( addr , str , strlen( str ) + 1 );
}

Ci sarebbe anche un'altra via, che non necessita di g++ ma si basa sul precompilatore, in pratica il risultato e' lo stesso dei template, ma se vuoi del codice C99 "pulito" ti puo' aiutare, probabilmente e' inutilmente macchinoso nel tuo caso, ma hai detto mai:
Code:
void EPROOM_write_ptr( unsigned addr , void* buff , unsigne length )
{
unsigned i;
while( length - i++ ) EPROOM.write( ((unsigned char*)addr) + i , buff[i] );
}

#define EPROOM_write( TYPE , ADDR , VAR ) EPROOM_write_ ## TYPE ( unsigned ADDR , VAR )

#define EPROOM_WRITE( TYPE ) void EPROOM_write_ ## TYPE ( unsigned addr , TYPE var ) \
{ \
EEPROM_write_ptr( addr , &var , sizeof(type) ); \
}
EPROOM_WRITE( unsigned char )
EPROOM_WRITE( unsigned short )
...
EPROOM_WRITE( signed short )
EPROOM_WRITE( signed long )

void foo()
{
EPROOM_write( unsigned int , 0xDEADBEAF, 12345 );
EPROOM_write( signed car , 0xABCDEFAB, 0x7F );
...
}

Good luck!
« Last Edit: August 06, 2012, 08:56:22 pm by cunctator » Logged

Pages: [1]   Go Up
Jump to: