错误无效使用 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 端点

http://192.168.1.9/readBatt/1

在您的浏览器中。 (将 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 中传递的值进行边界检查以确保您获得有效的电池编号) .