Come includere le funzioni della libreria <SD.h> in un file .c ?

Salve a tutti,
sto realizzando un server con microcoap su Arduino Due, costituito da un file principale (microcoap.ino) e altri file in C (endpoints.c, coap.c e coap.h); nel file enpoints.c devo aprire un file.txt contenuto nella microSD di Arduino, ma, dopo aver scritto il codice per aprire il file.txt, il compilatore mi trova questo errore:

'SD' undeclared (first use in this function)

Questo errore è causato dal fatto che non mi riconosce la funzione SD.begin(), che dovrebbe essere dichiarata nella libreria <SD.h>. Come potrei risolvere la cosa?

Ciao, essendo il tuo primo post, ti chiederei di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con attenzione il REGOLAMENTO ... Grazie. :)

Guglielmo

Hai messo in cima

#include <SD.h>

?

Si, in cima al file endpoints.c ho messo #include <SD.h>ma ho ugualmente l’ errore.

OK, allora posta tutto il codice, probabilmente c'è un errore da qualche altra parte, tipo un puntoevirgola mancante poco prima di SD.begin().

Il codice è un po' lungo, comunque puoi scaricarlo dal link:

https://dl.dropboxusercontent.com/u/53209900/endpoints.rar

l' istruzione SD.begin() è alla riga 576.

non puoi includere una classe in un file .C
rinomina il file in .cpp

Purtroppo modificare l’ estensione in .cpp mi costringerebbe a rivedere una grossa parte di codice. Avresti una altra soluzione? Potrei richiamare da quel punto del file endpoints.c un altro file .cpp che contenga la parte di codice che non mi viene compilata?

Se il problema è quello non c'è verso, le classi sono una feature del C++ che in C non è presente, per cui quel file deve essere compilato dal compilatore C++, non da quello C.

Perché dovresti rivedere una grande parte di codice? Il C++ è compatibile al 99.9999% col C!

Perché mi dà molti errori di compilazione, in particolare mi considera errori delle variabili di tipo uint8_t* che io ho "forzato" (cast) in char* e al momento non saprei come risolvere questo problema.

Dovrebbe dare solo un warning. Alla peggio puoi cambiare i cast in reinterpret_cast<>.

Purtroppo mi dà errore…sto provando a usare reinterpreter_cast<> ma mi dà questo errore:

endpoints.cpp:557: error: reinterpret_cast from type 'const uint8_t* {aka const unsigned char*}' to type 'char*' casts away qualifiers

    char* pointer = reinterpret_cast<char*>(inpkt->opts[i].buf.p);

Stai togliendo anche il const. Se vuoi mantenerlo:

const char* pointer = reinterpret_cast<const char*>(inpkt->opts[i].buf.p);

Oppure se vuoi toglierlo (cosa tendenzialmente poco saggia):

char* pointer = reinterpret_cast<char*>(const_cast<uint8_t *> (inpkt->opts[i].buf.p));

mi dispiace ma devi ripartire da 0.

crea il file .cpp e "re"inizia a scrivere il codice, in caso di errore posta qui sul forum(con gli apposti tag code), ma un intero codice pensato per il C se non sei bravo(altrimenti avresti usato extern C per le parti non cpp), difficilmente andrà sotto CPP.

Per la prossima volta ricordati che solo il "core"(aka framework) Arduino viene compilato con gcc, il resto con g++, quindi ti devi sottomettere a questa volontà.

E non posso, da questo punto, "migrare" in un file .cpp, nel quale scriverei solo la parte contenente le funzioni per gestire la miscoSD?

Se ne sei in grado puoi anche fare qualcosa del genere, ma a mio avviso ti vai a complicare la vita più che a sistemare i cast. Che poi, sono convinto che se li trasformi in (const char *) funzionino anche C-style.

guarda che se ti ho consigliato di riscriverlo da 0 è perchè il codice è pieno zeppo di errori! sopratutto sull'uso delle stringhe! Parti con il fare una cosa alla volta, testala e prosegui. Se hai problemi posta un codice compilabile tramite gli appositi tag code.

Grazie 1000 SukkoPera e VBextreme, ho risolto i problemi di incompatibilità, ora il compilatore mi dà tutto ok :wink: :slight_smile:

vbextreme:
Per la prossima volta ricordati che solo il “core”(aka framework) Arduino viene compilato con gcc, il resto con g++, quindi ti devi sottomettere a questa volontà.

Quindi, quando il file è .c viene compilato dal compilatore per C, cioè gcc, mentre quando il file è .cpp viene compilato dal compilatore per C++, cioè g++?

Gran parte degli errori erano dovuti a delle variabili “const”, quindi li ho risolti eliminando il “const”, dato che in fin dei conti sono variabili che il programma non prova mai a modificare.

si esattamente. Se chiami il tuo file.c allora compila GCC se lo chiami.cpp allora compila g++ le estensioni .ino sono sempre compilate con g++ Ti conviene sempre usare l'estensione .cpp mischiarle è complesso, se ad esempio ti crei una funzione che debba andare sia sotto C che sotto C++ devi fare così

#ifdef __cplusplus
extern "C" {
#endif

void miafunction(void);

#ifdef __cplusplus
}
#endif

il motivo principale è la decorazione dei nomi, il compilatore C e quello C++ modificano i nomi in maniera diversa, quindi bisogna informarlo su come agire.