I have a large sketch that I would like to break into multiple source files. Basically a library but not use a class (I have to understand classes much better first). The functions make use of global variables that I need to access in the main sketch and in the functions itself. I created an very small example that recreates the problem/scenario.
I am getting the following errors
func.cpp.o: In function `toggle()':
func.cpp:16: undefined reference to `state'
func.cpp:17: undefined reference to `pin'
func.cpp:19: undefined reference to `state'
func.cpp:21: undefined reference to `pin'
func.cpp:23: undefined reference to `state'
func.cpp.o: In function `toggleSetup()':
func.cpp:10: undefined reference to `pin'
var_test.cpp.o: In function `setup':
var_test.cpp:11: undefined reference to `pin'
My main sketch var_test.ino
// var_test.ino
#include <SoftwareSerial.h>
#include "func.h"
void setup() {
// put your setup code here, to run once:
pin = 5;
toggleSetup();
}
void loop() {
toggle();
delay(3000);
}
The variable needs to be declared in the header file (func.h) just like a function prototype. But it cannot be initialized in the header file. Instead the initialization can happen in either source file. Since my global vars are specific to the library, it makes the most sense to put the initialization into the func.cpp file.
In my actual project I initialized all the global variables in the header file. I did not do that in the example I posted, but the results are nonetheless the same. So here is a func.cpp with which the project will build just fine.
although state and pin are declared to be extern in func.h, and although func.h has been included to help the linker resolve references to them, you have not defined these two variables in the code you've shown. You need to do that.
I had declared them in func.h. But I have to initialize the variable in a global scope in the cpp or ino file. The variable cannot be initialized in the header file. That is the mistake I made.
"extern int foo;" -> declares a variable which essentially informs the compiler we intent to use it
"int foo;" -> defines the variable and causes memory to be allocated, but the content is undefined
"int foo = 42;" -> defines and initializes the variable, memory is allocated and set to the value (42)