错误无效使用 void 表达式。试图将参数传递给函数
Error invalid use of void expression. Trying to pass a parameter through to the function
我正在尝试初始化一个服务器,使其根据收到的请求看起来像特定的输入。它们有很多,所以我想用一个循环初始化它,如下所示:
void serverInit() {
for (int i = 1; i <= qty; i++) {
String s = "/readBatt" + i;
server.on(s, runTest(i));
}
server.begin();
Serial.println("Server started.");
}
它告诉我 server.on(s, runTest(i));
是对 void 表达式的无效使用。我知道它希望将其格式化为 server.on(s, runTest)
但函数 runTest(int n)
需要一个参数。如何将此参数传递给函数?
看来您正在使用 ESP32 Arduino 库中的 WebServer class。正如您已经了解到的,on()
方法中指定的回调不接受任何参数。
不过,您还有其他选择。您可以在 URL 路径中指定 'placeholder' - 使用大括号 - {}
。然后,在回调中,可以使用 pathArg()
方法检索相应的参数 - 该方法接受参数索引作为参数。
例子...
您可以将 API 端点定义为 /readBatt/<battery number>
。然后,要配置服务器以处理对此端点的请求,您可以使用类似
#include <uri/UriBraces.h>
server.on(UriBraces("/readBatt/{}"), runTest);
在您的回调中,您将按如下方式检索第一个参数...
static void runTest() {
String batteryNumber = server.pathArg(0);
Serial.println("Request to read battery");
String response = "You attempted to read battery " + batteryNumber;
response += ".\nThis endpoint is a placeholder. Check again soon!";
server.send(200, "text/plain", response);
}
最后...假设您的 ESP8266 运行 在本地 IP 地址 192.168.1.9 上。您可以通过打开
访问新的 API 端点
在您的浏览器中。 (将 1
替换为相关的电池编号。)
不幸的是,我认为 pathArg()
没有 return 整数的版本,因此您可能必须在某些时候执行转换。
您可以使用所谓的 "closure"。闭包允许您编写一个函数,该函数保留对其作用域外变量的访问。
闭包是使用 "lambda expression" 编写的 - 基本上是一个匿名函数。 C++ 的 lambda 表达式语法如下所示:
[capture variable list](argument list) { body}
捕获变量列表是您希望在正文中可用的变量列表。参数列表是调用者传入的普通函数参数列表。您可以这样编写所需的 lambda 表达式:
[i]() { runTest(i); }
并像这样使用它:
server.on(s, [i]() { runTest(i); });
明确地说,@David Collins 的回答是编写 Web 服务器的更好方法。在 URL 中使用一个参数比创建多个嵌入参数的 URL 更好。我只是在回答如何将参数传递给不带参数调用的函数的问题。如果您以更好的方式编写 Web 服务器代码,则无需执行此操作(尽管我会对 URL 中传递的值进行边界检查以确保您获得有效的电池编号) .
我正在尝试初始化一个服务器,使其根据收到的请求看起来像特定的输入。它们有很多,所以我想用一个循环初始化它,如下所示:
void serverInit() {
for (int i = 1; i <= qty; i++) {
String s = "/readBatt" + i;
server.on(s, runTest(i));
}
server.begin();
Serial.println("Server started.");
}
它告诉我 server.on(s, runTest(i));
是对 void 表达式的无效使用。我知道它希望将其格式化为 server.on(s, runTest)
但函数 runTest(int n)
需要一个参数。如何将此参数传递给函数?
看来您正在使用 ESP32 Arduino 库中的 WebServer class。正如您已经了解到的,on()
方法中指定的回调不接受任何参数。
不过,您还有其他选择。您可以在 URL 路径中指定 'placeholder' - 使用大括号 - {}
。然后,在回调中,可以使用 pathArg()
方法检索相应的参数 - 该方法接受参数索引作为参数。
例子...
您可以将 API 端点定义为 /readBatt/<battery number>
。然后,要配置服务器以处理对此端点的请求,您可以使用类似
#include <uri/UriBraces.h>
server.on(UriBraces("/readBatt/{}"), runTest);
在您的回调中,您将按如下方式检索第一个参数...
static void runTest() {
String batteryNumber = server.pathArg(0);
Serial.println("Request to read battery");
String response = "You attempted to read battery " + batteryNumber;
response += ".\nThis endpoint is a placeholder. Check again soon!";
server.send(200, "text/plain", response);
}
最后...假设您的 ESP8266 运行 在本地 IP 地址 192.168.1.9 上。您可以通过打开
访问新的 API 端点在您的浏览器中。 (将 1
替换为相关的电池编号。)
不幸的是,我认为 pathArg()
没有 return 整数的版本,因此您可能必须在某些时候执行转换。
您可以使用所谓的 "closure"。闭包允许您编写一个函数,该函数保留对其作用域外变量的访问。
闭包是使用 "lambda expression" 编写的 - 基本上是一个匿名函数。 C++ 的 lambda 表达式语法如下所示:
[capture variable list](argument list) { body}
捕获变量列表是您希望在正文中可用的变量列表。参数列表是调用者传入的普通函数参数列表。您可以这样编写所需的 lambda 表达式:
[i]() { runTest(i); }
并像这样使用它:
server.on(s, [i]() { runTest(i); });
明确地说,@David Collins 的回答是编写 Web 服务器的更好方法。在 URL 中使用一个参数比创建多个嵌入参数的 URL 更好。我只是在回答如何将参数传递给不带参数调用的函数的问题。如果您以更好的方式编写 Web 服务器代码,则无需执行此操作(尽管我会对 URL 中传递的值进行边界检查以确保您获得有效的电池编号) .