[RESOLVED]"String undeclared" issue in my header

Hi !

Im in a big project and I communicate with a GSM Click, using AltSoftSerial, this works fine (I can send a sms if I cross the hardware serial and AltSoftSerial, in order to write from my PC terminal to the modem the right AT commands). But for my application I need to have a lot of functions in an extern file, so I made a .c and a .h files.

My problem, now, is that I get many error, even in the header file which looks fine to me. I'll paste down there the header file and the error log, and attach the .c file and the .ino. In my opinion the .ino one and the .c one are not really relevant (maybe the top of the files is), anyway you'll know this better than I do so I put everything here.

The errors are things like "String undeclared", or "myGsmSerial undeclared" (declared at top of the file), or "error: expected ')' before 'strPinCode'" where strPinCode is a function parameter, and is supposed to be a String.

I'm using an Arduino Uno and my IDE is the Arduino one, 1.5.6-r2.

GSMClick.h

#ifndef __GSMCLICK__
#define __GSMCLICK__
#include <Arduino.h>
#include <AltSoftSerial.h>

/**************
* void gsm_setup(void)
* Configuration of the serial communication between the modem and the Arduino
* Beginning of the serial communication
* Configuration of the modem with the serial communication
**************/
void gsm_setup(void);

/**************
* int gsm_pinCode(String pinCode)
* Enters the PIN Code to unlock the SIM card
* String pinCode : PIN code of the inserted SIM card
* Returns an int for information. Possible return values :
* 0 : The PIN CODE is correct, therefore the SIM card is correctly unlocked
* -1 : The PIN CODE is wrong
* -2 : You need to enter the PUK code, call gsm_pukCode()
* -3 : timeout, modem didn't answer in time
* -4 : Other error, can't understand modem
* -5 : No SIM card inserted
**************/
int gsm_pinCode(String strPinCode);

/**************
* int gsm_pukCode(String pukCode, String newPinCode)
* Enters the PUK code to unlock the PUK-locked SIM card, and changes the PIN code
* String pukCode : The PUK code of the SIM card
* String newPinCode : The new PIN code of the SIM card 
* Returns an int for information. Possible return values :
* 0 : The PUK code is correct and the PIN code was correctly modified
* -1 : SIM card already unlocked
* -2 : SIM card asks for SIM code, not PUK code
* -3 : Timeout, modem didn't answer in time
* -4 : Other error, can't understand modem
* -5 : No SIM card
**************/
int gsm_pukCode(String strPukCode, String strNewPinCode);

/**************
* int gsm_sendSMS(String smsText)
* Send a SMS
* String strSmsText : Content of the SMS, maximum 170 char, if more, last chars will be cut
* String strNumber : Number that will receive the SMS, must be in format "+12345678901" 
* Return an int for information. Possible return values :
* 0 : The SMS was correctly sent
* -1 : SIM is PIN-locked 
* -2 : SIM is PUK-locked
* -3 : Timeout, modem didn't answer in time
* -4 : Can't understand modem
* -5 : No SIM card
**************/
int gsm_sendSMS(String strSmsText, String strNumber);

/**************
* int gsm_getTime(int* hours, int* minutes)
* Get the actual time
* int* hours : Pointer on the hours' var
* int* minutes : Pointer on the minutes' var
* Return an int. Possible values : 
* 0 : Time has been put in the right variables
* -1 : SIM needs the PIN code, call gsm_pinCode()
* -2 : SIM needs the PUK code, call gsm_pukCode()
* -3 : Timeout, the modem didn't answer in time
* -4 : Can't understand modem
* -5 : No SIM card
**************/
void gsm_getTime(int* hours, int* minutes);

/**************
* String gsm_readGsmSerial(void)
* Read the next incoming String on Serial, the String ends with \r\n
* Return value : 
* String : The String that has been read
**************/
String gsm_readGsmSerial(void);

/**************
* void gsm_cleanSerial(void)
* Read the serial until there's nothing more to read
**************/
void gsm_cleanSerial(void);


/*****************************************************
// STATIC METHODS
/****************************************************/

/**************
* static int gsm_checkOk(void)
* Check if the GSM sends "OK", "ERROR", anything else or doesn't anwer in time
* Return an int. Possible values : 
* 0 : Answer is "OK"
* -1 : Answer is "ERROR"
* -2 : Answer is something else
* -3 : Timeout, the modem didn't answer in time
**************/
static int gsm_checkOk(void);

/**************
* static void gsm_turnOn(void)
* Turns the GSM on after a 3s reset, lasts almost 5s
**************/
static void gsm_turnOn(void);

/**************
* static int gsm_waitAnswer(void)
* Wait for an answer
* Return an int. Possible values : 
* 0 : There is an answer
* -1 : There is no answer in time
**************/
static int gsm_waitAnswer(void);

/**************
* static int gsm_checkSIM(void)
* Asks the SIM state 
* Return an int. Possible values : 
* 0 : SIM is READY
* -1 : SIM needs the PIN code, call gsm_pinCode()
* -2 : SIM needs the PUK code, call gsm_pukCode()
* -3 : Timeout, the modem didn't answer in time
* -4 : Can't understand modem
* -5 : No SIM card (not implemented yet) TODO
**************/
static int gsm_checkSIM(void);
#endif

Error log

Arduino : 1.5.6-r2 (Windows 7), Carte : "Arduino Uno"

In file included from GSMClick.c:1:
GSMClick.h:26: error: expected ')' before 'strPinCode'
GSMClick.h:41: error: expected ')' before 'strPukCode'
GSMClick.h:56: error: expected ')' before 'strSmsText'
GSMClick.h:79: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'gsm_readGsmSerial'
GSMClick.c:9: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'myGsmSerial'
GSMClick.c: In function 'gsm_setup':
GSMClick.c:22: error: 'myGsmSerial' undeclared (first use in this function)
GSMClick.c:22: error: (Each undeclared identifier is reported only once
GSMClick.c:22: error: for each function it appears in.)
GSMClick.c: At top level:
GSMClick.c:52: error: expected ')' before 'strPinCode'
GSMClick.c:98: error: expected ')' before 'strPukCode'
GSMClick.c:152: error: expected ')' before 'strSmsText'
GSMClick.c: In function 'gsm_getTime':
GSMClick.c:271: error: 'String' undeclared (first use in this function)
GSMClick.c:271: error: expected ';' before 'strAnswer'
GSMClick.c:290: error: 'myGsmSerial' undeclared (first use in this function)
GSMClick.c:300: error: 'strAnswer' undeclared (first use in this function)
GSMClick.c: At top level:
GSMClick.c:314: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'gsm_readGsmSerial'
GSMClick.c: In function 'gsm_cleanSerial':
GSMClick.c:351: error: 'myGsmSerial' undeclared (first use in this function)
GSMClick.c: In function 'gsm_checkOk':
GSMClick.c:375: error: 'strAnswer' undeclared (first use in this function)
GSMClick.c: In function 'gsm_waitAnswer':
GSMClick.c:418: error: 'gsm_readGsmSerial' undeclared (first use in this function)
GSMClick.c:418: error: expected ')' before 'or'
GSMClick.c: In function 'gsm_checkSIM':
GSMClick.c:442: error: 'String' undeclared (first use in this function)
GSMClick.c:442: error: expected ';' before 'strAnswer'
GSMClick.c:446: error: 'myGsmSerial' undeclared (first use in this function)
GSMClick.c:452: error: 'strAnswer' undeclared (first use in this function)

I did search on the web about this problem and I only found some old post from the time String wasn't in the basic Arduino lib. If someone could tell me what is wrong, probably in my header, that'd be very kind.

Thanks for the reading, and hopefully you'll see better than me what's wrong in this ...

GSMClick.c (11.4 KB)

GSMClick.ino (417 Bytes)

so I made a .c and a .h files.

Here's a clue. The Arduino is programmed using C++, which goes in a .cpp file.

C++ supports overloaded methods. How do you suppose that works? Simple, really. The REAL name of the function you are calling IS unique. The compiler generates the name based on the method names and the types of the input arguments. When you call a function, the same name mangling takes place, so the right function can be located in the object file.

When you compile your ino file, it gets converted to a cpp file, and the C++ makes name mangling happen.

When you compile your c file, the C compiler does not do name mangling.

When your C++ code tries to call a function using the name it has manufactured, that name does not exist in the object file that the C compiler created.

There are ways to use c files in a cpp application, but its easier just to go along with the fact that you are programming in C++ and use the appropriate extension.

Thanks ! This was helpful, I think I don't have any problems with Strings now.

I have another little issue and this is probably only because I did put a declaration in the wrong place. I have this error :

GSMClick.cpp:10: error: 'AltSoftSerial' does not name a type

I didn't change anything in the files except the extension of the .c (which is now .cpp).

I think the line where I declare the serial ("GSMClick.cpp:10: error: 'AltSoftSerial' does not name a type") isn't in the right place, but could you tell me where I should put it ?

This serial (AltSoftSerial, and particularly the instance named myGsmSerial) is only used in the GSMClick.c file, which will be used by others files later. Sometimes for debug purpose I use this serial in the .ino file.

I tried without the "extern", didn't change anything to the errors.

I'm sure that the fine folks at http://snippets-r-us.com can help you with your snippets. Here, we need to see ALL of your code - the header files, the source files, and the sketch.

One thing you need to know is that you can NOT hide the use of a library. If you use AltSoftSerial.h in your library, you MUST include it in your sketch, too.

Thanks for your answer. My whole code is in the first post and in the attached files and hasn't been changed since my first post here, except for the .cpp extension.

I don't understand what you mean when you say that I can't hide a library. In the .cpp file, where I use this library, I include the corresponding .h file, and in this .h file I do include the AltSoftSerial.h.

You can see this in my first post's header and .c files.

My whole code is in the first post and in the attached files and hasn't been changed since my first post here, except for the .cpp extension.

So, when the IDE is asked to verify your code, it copies GSMClick.ino to GSMClick.cpp. Oops. There goes your GSMClick.cpp file.

NEVER create a sketch with the same name as a library.

I don't understand what you mean when you say that I can't hide a library. In the .cpp file, where I use this library, I include the corresponding .h file, and in this .h file I do include the AltSoftSerial.h.

You do NOT include AltSoftSerial.h in the sketch. So, the compiler KNOWS that it doesn't need to have AltSoftSerial around. So, the fact that you try to use it in your library means that you are doomed to failure.

Okay, thanks gain.

I did change the name of the .ino file (and folder), and I moved "#include AltSoftserial" from the .h file to the .ino file.

Here's the error log :

Arduino : 1.5.6-r2 (Windows 7), Carte : "Arduino Uno"

GSMClick.cpp:9: error: 'AltSoftSerial' does not name a type
GSMClick.cpp: In function 'void gsm_setup()':
GSMClick.cpp:22: error: 'myGsmSerial' was not declared in this scope
GSMClick.cpp: In function 'int gsm_pinCode(String)':
GSMClick.cpp:66: error: 'myGsmSerial' was not declared in this scope
GSMClick.cpp: In function 'int gsm_pukCode(String, String)':
GSMClick.cpp:121: error: 'myGsmSerial' was not declared in this scope
GSMClick.cpp: In function 'int gsm_sendSMS(String, String)':
GSMClick.cpp:169: error: 'myGsmSerial' was not declared in this scope
GSMClick.cpp:234: error: expected `;' before string constant
GSMClick.cpp: In function 'void gsm_getTime(int*, int*)':
GSMClick.cpp:285: error: return-statement with a value, in function returning 'void'
GSMClick.cpp:290: error: 'myGsmSerial' was not declared in this scope
GSMClick.cpp:297: error: return-statement with a value, in function returning 'void'
GSMClick.cpp:303: error: return-statement with a value, in function returning 'void'
GSMClick.cpp: In function 'String gsm_readGsmSerial()':
GSMClick.cpp:320: error: 'myGsmSerial' was not declared in this scope
GSMClick.cpp: In function 'void gsm_cleanSerial()':
GSMClick.cpp:351: error: 'myGsmSerial' was not declared in this scope
GSMClick.cpp: In function 'int gsm_checkOk()':
GSMClick.cpp:375: error: 'strAnswer' was not declared in this scope
GSMClick.cpp:382: error: 'strAnswer' was not declared in this scope
GSMClick.cpp: In function 'int gsm_waitAnswer()':
GSMClick.cpp:418: error: request for member 'available' in 'gsm_readGsmSerial', which is of non-class type 'String ()()'
GSMClick.cpp:422: error: request for member 'available' in 'gsm_readGsmSerial', which is of non-class type 'String ()()'
GSMClick.cpp: In function 'int gsm_checkSIM()':
GSMClick.cpp:446: error: 'myGsmSerial' was not declared in this scope

I attach the 3 files of my project in this message. For the errors, only the one about myGsmSerial are interressing me. Others may come from uncompleted code or little things I did forget, I'll correct them later.

I still don't understand where I have to include the serial library and where I have to declare the AltsoftSerial variable that I use in my .cpp file...

Anyway, thanks a lot for your answers !

GSMClick.cpp (11.4 KB)

GSMClick.h (4.07 KB)

GsmUse.ino (444 Bytes)

I did change the name of the .ino file (and folder), and I moved "#include AltSoftserial" from the .h file to the .ino file.

Who said anything about MOVING the #include statement? It needs to be in BOTH source files (the sketch is a source file).

This works fine, thanks again !