我正在尝试开始使用PlatformIO,并遇到了包含优先级和/或可变范围的问题。
我的代码由一个src/main.cpp
程序以及位于lib/<libname>/*.cpp/h
位置的几个私有库组成。
我想要一个外部类(Syslog)的全局对象,我的主程序以及我添加的任何私有库都可以访问该外部类。
我目前已经尝试了两种方法,都拒绝编译:
使用extern关键字在main.cpp中创建对象,然后在setup()
中初始化对象,如下所示:
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!");
}
这会导致编译器错误,例如:
lib\GPSHandler\GPSHandler.cpp:22:4: error: 'syslog' was not declared in this scope
我尝试的第二种方法(在Arduino IDE中有效)是创建一个小的SyslogHelper.h
文件,该文件创建了extern Syslog syslog;
对象,然后将该帮助文件包含在我的所有私有库中,例如所以:
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!");
}
当我尝试在PlatformIO中进行编译时,它失败了,因为在尝试编译SyslogHelper.h时,它似乎不知道<Syslog.h>
文件的位置:
In file included from lib\GPSHandler\GPSHandler.cpp:7:0:
src/SyslogHelper.h:4:20: fatal error: Syslog.h: No such file or directory
答案 0 :(得分:1)
虽然我意识到您说要在库和私有库之间共享全局对象,但我要断言这不是最佳的设计模式,因为它脆弱且容易出错(根据您的经验)。更好的方法是将在主代码中创建的SysLog
对象作为参数传递给需要它的任何方法。更好的原因是因为您要明确声明然后可以使用Syslog
对象的方法。
但是,如果您确实必须具有全局变量,则第二好的模式是使用看起来像这样的访问器类:
SysLogHelper.h
#ifndef __SysLogHelper_h__
#define __SysLogHelper_h__
#include <Syslog.h>
class SysLogHelper {
private:
Syslog *_instance;
public:
static Syslog& instance( void );
Syslog();
virtual ~Syslog()
}
#endif // __SysLogHelper_h__
SysLogHelper.cpp
#include "SysLogHelper.h"
SysLogHelper gSysLogHelper();
Syslog& SysLogHelper::instance( void ) {
return gSysLogHelper._instance;
}
SysLogHelper::SysLogHelper() {
_instance = Syslog(SyslogUDP, "255.255.255.255", 514, "FlyballETS", "FlyballETSApp", LOG_INFO, SYSLOG_PROTO_BSD);
}
SysLogHelper::~SysLogHelper() {
delete _instance;
}
然后,在代码中要使用SysLog
对象的任何地方,只需包含SysLogHelper.h
标头,并通过调用static方法使用SysLog
实例即可,如下所示:< / p>
#include "SyslogHelper.h"
void GPSHandlerClass::init(HardwareSerial * SerialPort)
{
SyslogHelper::instance().logf_P("GPS Class initialized!");
}
可以根据自己的喜好随意重命名。同样,有了一些创造力,您可以在此访问器类中拥有多个SysLog
对象,每个对象的配置都不同。