How to create global object accessible to src/ code as well as lib/ libraries?


#1

Cross-post from stackoverflow:

I’m trying to get started with PlatformIO and have hit a wall with include priorities and/or variable scopes.

My code consists of a src/main.cpp program as well as several private libraries which reside in the lib/<libname>/*.cpp/h location.

I want to have a global object of an external class (Syslog) which is accessible to both my main program as well as any private libraries I’ve added.

I’ve currently tried 2 approaches, which both refuse to compile:


Create the object in main.cpp with the extern keyword, initialize the object in setup() like so:

src/main.cpp:

#include <Syslog.h>
#include <WiFiUdp.h>
WiFiUDP SyslogUDP;
extern Syslog syslog;
void setup()
{
   syslog = Syslog(SyslogUDP, "255.255.255.255", 514, "FlyballETS", "FlyballETSApp", LOG_INFO, SYSLOG_PROTO_BSD);
}

lib/GPSHandler/GPSHandler.cpp:

void GPSHandlerClass::init(HardwareSerial * SerialPort)
{
   syslog.logf_P("GPS Class initialized!");
}

This results in compiler errors like:

lib\GPSHandler\GPSHandler.cpp:22:4: error: 'syslog' was not declared in this scope

The 2nd approach I tried (this works in Arduino IDE), was creating a small SyslogHelper.h file, which created the extern Syslog syslog; object, and then include this helper file in all my private libs, like so:

src/main.cpp:

#include "SyslogHelper.h"
#include <WiFiUdp.h>
WiFiUDP SyslogUDP;

void setup()
{
   syslog = Syslog(SyslogUDP, "255.255.255.255", 514, "FlyballETS", "FlyballETSApp", LOG_INFO, SYSLOG_PROTO_BSD);
}

src/SyslogHelper.h:

#include <Syslog.h>
extern Syslog syslog;

lib/GPSHandler/GPSHandler.cpp:

#include "SyslogHelper.h"
void GPSHandlerClass::init(HardwareSerial * SerialPort)
{
   syslog.logf_P("GPS Class initialized!");
}

When I try to compile this in PlatformIO, it fails because at the time it tries to compile SyslogHelper.h, it doesn’t seem to be aware of the location of the <Syslog.h> file:

In file included from lib\GPSHandler\GPSHandler.cpp:7:0:
src/SyslogHelper.h:4:20: fatal error: Syslog.h: No such file or directory

#2

Yes because you havent’ declared the syslog object as an external object in GPSHandler.cpp.

If your Syslog.h inside src you could add it to the include path by going into your platformio.ini file and adding

build_flags = -I src/


Actually, most Arduino libraries with such a singleton structure / one pre-instantiated, global object are written differently. You declare the global object as extern in your library’s header file (instead of in your sketch) and instantiate in one of the CPP file. Look for example at https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WiFi/src, the files ESP8266WiFi.h and ESP8266WiFi.cpp with respect to the object ESP8266WiFiClass WiFi.