ESP8266WebServer 在 class 中设置一个值
ESP8266WebServer setting a value inside a class
我在使用 ESP8266WebServer 时遇到了一些问题。我的 WebServer{} class 包裹在 ESP8266WebServer 对象周围,看起来像这样:
头文件:
#include <WiFiClient.h>
#ifndef WebServer_h
#define WebServer_h
#include "Arduino.h"
class WebServer {
public:
WebServer();
void begin();
void handleClient();
void finishedProcessingData(String clientReply);
String queryString;
private:
// page/url handlers
friend void handleSomeData();
};
#endif
Cpp 文件:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include "Arduino.h"
#include "WebServer.h"
ESP8266WebServer server(80);
int aNumberHere = 0;
String queryString = "";
WebServer::WebServer(){
}
void handleSomeData(){
aNumberHere++;
queryString = "";
// this loop appends all the queries fro the query string back into a query string
// (not sure if there is an easier way to grab this directly from the server api)
int totalArgs = server.args();
for (int counter = 0; counter < totalArgs; counter++){
queryString += server.argName(counter) +"="+ server.arg(counter);
if(counter < (totalArgs - 1)){
queryString += "&";
}
}
Serial.println(queryString);
Serial.println(aNumberHere);
}
void WebServer::handleClient(){
server.handleClient();
}
void WebServer::begin(){
server.on("/data.html", handleSomeData);
server.begin();
}
void WebServer::finishedProcessingData(String clientReply){
// empty the string so it isn't cached (just in case)
Serial.print("Sending reply back to client: ");
Serial.println(clientReply);
queryString = "";
server.send(200, "text/plain", clientReply);
}
想法是从 http 请求中获取查询字符串,进行一些处理,然后 return 响应。
外部调用方式是:
WebServer webServer;
String processingResult;
void setup(){
webServer.begin();
}
void loop(){
delay(10);
webServer.handleClient();
// check if the query string has stuff in it, if it doesn't then WebServer.handleSomeData() never fired, thus no request yet
if(webServer.queryString != ""){
// do stuff that results in a string being returned
processingResult = handWavyMagic();
// then respond back to client
webServer.finishedProcessingData(processingResult);
}
}
我的问题是,从我的外部循环(在我的主草图中)来看,"webServer.queryString" 总是等于一个空字符串。如果我从 handleSomeData() 中打印出 "queryString",我可以从 "handleSomeData()" 中看到打印结果(这是正确的),但它似乎无法设置它 'outside'方法。我确实检查过它是否能够访问和修改变量(这就是打印 "aNumberHere" 的原因)并且似乎没有问题;每次我转到相应的 url.
时,"aNumberHere" 都会按预期递增
我唯一的怀疑是 "queryString" 是一个 String 对象,由于某种原因无法设置,而 "aNumberHere" 是一个原始的 int,这很好。这是正确的还是这里发生了其他事情?
我也试过使 "queryString" 成为一个静态变量,但没有成功——要么我做错了,要么就是那样也行不通。
我是朋友函数的新手(好吧,实际上是 c/c++ 的新手——欢迎任何建议),尽管我读到它应该能够访问 classes私有属性很好,所以我不确定如何解决这个问题。
有什么想法吗?
有 2 个不同的变量叫做 queryString
:
- 在
WebServer.cpp
中声明的全局
- 在
WebServer.h
中声明的WebServer成员
在回调handleSomeData
中你设置了全局的,但是在loop
和finishedProcessingData
中你访问了WebServer的成员。
要使代码正常工作,您可以删除 WebServer 的成员并使用全局成员(就像您对 aNumberHere 所做的那样),如下所示:
extern String queryString;
void loop(){
delay(10);
webServer.handleClient();
// check if the query string has stuff in it, if it doesn't then WebServer.handleSomeData() never fired, thus no request yet
if(queryString != ""){
// do stuff that results in a string being returned
processingResult = handWavyMagic();
// then respond back to client
webServer.finishedProcessingData(processingResult);
queryString = "";
}
}
我知道,OP 帮助解决他的问题有点晚了,但也许其他读者会发现这很有用。
为了避免在 class 的内部和外部拆分 logic/data 的部分,将所有内容都放在 内部 会更优雅。使用回调到 class 实例的非静态方法有点棘手(我在当前项目中通过艰难的方式学到了它),但这是替代方案:
void WebServer::begin()
{
// instead of server.on("/data.html", handleSomeData);
server.on("/data.html", std::bind(&WebServer::handleSomeData, this));
server.begin();
}
void WebServer::handleSomeData()
{
// do whatever you need
}
这使用 std:bind() 将实例方法及其 this
指针绑定到回调。因此,所有内容都包含在 Web 服务器实例中,这是一种更简洁的方法。
我在使用 ESP8266WebServer 时遇到了一些问题。我的 WebServer{} class 包裹在 ESP8266WebServer 对象周围,看起来像这样:
头文件:
#include <WiFiClient.h>
#ifndef WebServer_h
#define WebServer_h
#include "Arduino.h"
class WebServer {
public:
WebServer();
void begin();
void handleClient();
void finishedProcessingData(String clientReply);
String queryString;
private:
// page/url handlers
friend void handleSomeData();
};
#endif
Cpp 文件:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include "Arduino.h"
#include "WebServer.h"
ESP8266WebServer server(80);
int aNumberHere = 0;
String queryString = "";
WebServer::WebServer(){
}
void handleSomeData(){
aNumberHere++;
queryString = "";
// this loop appends all the queries fro the query string back into a query string
// (not sure if there is an easier way to grab this directly from the server api)
int totalArgs = server.args();
for (int counter = 0; counter < totalArgs; counter++){
queryString += server.argName(counter) +"="+ server.arg(counter);
if(counter < (totalArgs - 1)){
queryString += "&";
}
}
Serial.println(queryString);
Serial.println(aNumberHere);
}
void WebServer::handleClient(){
server.handleClient();
}
void WebServer::begin(){
server.on("/data.html", handleSomeData);
server.begin();
}
void WebServer::finishedProcessingData(String clientReply){
// empty the string so it isn't cached (just in case)
Serial.print("Sending reply back to client: ");
Serial.println(clientReply);
queryString = "";
server.send(200, "text/plain", clientReply);
}
想法是从 http 请求中获取查询字符串,进行一些处理,然后 return 响应。
外部调用方式是:
WebServer webServer;
String processingResult;
void setup(){
webServer.begin();
}
void loop(){
delay(10);
webServer.handleClient();
// check if the query string has stuff in it, if it doesn't then WebServer.handleSomeData() never fired, thus no request yet
if(webServer.queryString != ""){
// do stuff that results in a string being returned
processingResult = handWavyMagic();
// then respond back to client
webServer.finishedProcessingData(processingResult);
}
}
我的问题是,从我的外部循环(在我的主草图中)来看,"webServer.queryString" 总是等于一个空字符串。如果我从 handleSomeData() 中打印出 "queryString",我可以从 "handleSomeData()" 中看到打印结果(这是正确的),但它似乎无法设置它 'outside'方法。我确实检查过它是否能够访问和修改变量(这就是打印 "aNumberHere" 的原因)并且似乎没有问题;每次我转到相应的 url.
时,"aNumberHere" 都会按预期递增我唯一的怀疑是 "queryString" 是一个 String 对象,由于某种原因无法设置,而 "aNumberHere" 是一个原始的 int,这很好。这是正确的还是这里发生了其他事情?
我也试过使 "queryString" 成为一个静态变量,但没有成功——要么我做错了,要么就是那样也行不通。
我是朋友函数的新手(好吧,实际上是 c/c++ 的新手——欢迎任何建议),尽管我读到它应该能够访问 classes私有属性很好,所以我不确定如何解决这个问题。
有什么想法吗?
有 2 个不同的变量叫做 queryString
:
- 在
WebServer.cpp
中声明的全局
- 在
WebServer.h
中声明的WebServer成员
在回调handleSomeData
中你设置了全局的,但是在loop
和finishedProcessingData
中你访问了WebServer的成员。
要使代码正常工作,您可以删除 WebServer 的成员并使用全局成员(就像您对 aNumberHere 所做的那样),如下所示:
extern String queryString;
void loop(){
delay(10);
webServer.handleClient();
// check if the query string has stuff in it, if it doesn't then WebServer.handleSomeData() never fired, thus no request yet
if(queryString != ""){
// do stuff that results in a string being returned
processingResult = handWavyMagic();
// then respond back to client
webServer.finishedProcessingData(processingResult);
queryString = "";
}
}
我知道,OP 帮助解决他的问题有点晚了,但也许其他读者会发现这很有用。
为了避免在 class 的内部和外部拆分 logic/data 的部分,将所有内容都放在 内部 会更优雅。使用回调到 class 实例的非静态方法有点棘手(我在当前项目中通过艰难的方式学到了它),但这是替代方案:
void WebServer::begin()
{
// instead of server.on("/data.html", handleSomeData);
server.on("/data.html", std::bind(&WebServer::handleSomeData, this));
server.begin();
}
void WebServer::handleSomeData()
{
// do whatever you need
}
这使用 std:bind() 将实例方法及其 this
指针绑定到回调。因此,所有内容都包含在 Web 服务器实例中,这是一种更简洁的方法。