【发布时间】:2019-08-19 21:29:42
【问题描述】:
我有一个相当不错的模板(如在代码的 sn-p 中),每当我需要一个单例类时,我就会退出。我现在正尝试在我的项目中应用它,以允许我控制 Web 服务器的单个实例。我可以制作一个 Web 服务器,而无需将其封装在我的课堂上。当我试图将它包含在课堂上时,我显然太不熟练了,无法将其完成。
我在这里尝试了明显的谷歌搜索。我已经阅读了相关的帖子。我确信这并不意味着我有一个独特的问题,只是我还没有找到解决问题的正确方法。这是我正在使用的:
webserver.h:
#include <ESP8266WebServer.h>
#include <FS.h>
class WebServer {
private:
// Singleton Declarations
static bool instanceFlag;
static WebServer *single;
WebServer() {}
// Other Declarations
FS *filesystem;
ESP8266WebServer server();
String getContentType(String);
bool handleFileRead(String);
public:
// Singleton Declarations
static WebServer* getInstance();
~WebServer() {instanceFlag = false;}
// Other Declarations
void initialize(int);
void handleLoop();
};
webserver.cpp:
#include "webserver.h"
bool WebServer::instanceFlag = false;
WebServer* WebServer::single = NULL;
WebServer* WebServer::getInstance() {
if(!instanceFlag) {
single = new WebServer();
instanceFlag = true;
return single;
} else {
return single;
}
}
void WebServer::initialize (int port) {
ESP8266WebServer server(port);
FS *filesystem;
filesystem->begin();
Serial.print("Open: http://");
Serial.print(WiFi.hostname().c_str());
Serial.println(".local");
server.onNotFound([]() {
if (!single->handleFileRead(single->server.uri())) {
single->server.send(404, "text/plain", "404: File not found.");
}
});
server.begin();
Serial.print("HTTP server started on port ");
Serial.print(port);
Serial.println(".");
}
String WebServer::getContentType(String filename) {
if (single->server.hasArg("download")) {
return "application/octet-stream";
} else if (filename.endsWith(".htm")) {
return "text/html";
} else if (filename.endsWith(".html")) {
return "text/html";
} else if (filename.endsWith(".css")) {
return "text/css";
} else if (filename.endsWith(".js")) {
return "application/javascript";
} else if (filename.endsWith(".png")) {
return "image/png";
} else if (filename.endsWith(".gif")) {
return "image/gif";
} else if (filename.endsWith(".jpg")) {
return "image/jpeg";
} else if (filename.endsWith(".ico")) {
return "image/x-icon";
} else if (filename.endsWith(".xml")) {
return "text/xml";
} else if (filename.endsWith(".pdf")) {
return "application/x-pdf";
} else if (filename.endsWith(".zip")) {
return "application/x-zip";
} else if (filename.endsWith(".gz")) {
return "application/x-gzip";
} else {
return "text/plain";
}
}
bool WebServer::handleFileRead(String path) {
Serial.println("handleFileRead: " + path);
if (path.endsWith("/")) {
path += "index.htm";
}
String contentType = getContentType(path);
String pathWithGz = path + ".gz";
if (filesystem->exists(pathWithGz) || filesystem->exists(path)) {
if (filesystem->exists(pathWithGz)) {
path += ".gz";
}
File file = filesystem->open(path, "r");
single->server.streamFile(file, contentType);
file.close();
return true;
}
return false;
}
void WebServer::handleLoop() {
single->server.handleClient();
}
我得到的错误都类似于以下内容:
src\webserver.cpp: In member function 'bool WebServer::handleFileRead(String)':
src\webserver.cpp:81:23: error: 'WebServer::single->WebServer::server' does not have class type
single->server.streamFile(file, contentType);
我得到“没有类类型”的想法,我只是不知道这意味着什么。在我看来,“single”是指向该类的指针,所以我不清楚该引用是什么不起作用。
显然,有大量示例如何在不封装 Web 服务器的情况下创建它。我需要为这个项目做的其他事情有助于创建该需求。
【问题讨论】:
-
FWIW,如果你要制作单例,你应该使用Meyers' Singleton
-
WebServer::server看起来很像一个函数:ESP8266WebServer server();你确定你想要那些括号,还是我们应该把它当作错字关闭? -
@user4581301,不确定您的确切意思。我看到的唯一括号在 server.onNotFound 处理程序中,当我删除它时,我遇到了同样的问题。我确定 'WebServer::single->WebServer::server' 部分正在用我需要的信息向我尖叫,我猜我只是不明白。
-
感谢您的参考@NathanOliver。我会看看,虽然我怀疑实例化/使用 lib 类会犯同样的错误。
-
道歉不够清楚。
ESP8266WebServer server();末尾的括号意外地声明了一个函数而不是定义了一个变量,从而导致了很久以后的错误消息。函数不是类,因此您不能使用.访问成员。您会在编程中发现的一件事是,实际的错误通常不在崩溃现场附近。
标签: c++ class arduino esp8266 arduino-esp8266