ESP8266WiFi - server.on( - declarition of variable required inside function

Hello, again:

Linux Mint 22, VSCode 1.127, ESP8266

I am working on a web server app using ESP8266WiFi.h

In setup() I have …

g_OTA_server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
char ota_info_str[256];
char our_ip_address[20];

    sprintf(our_ip_address, "%s", WiFi.localIP().toString().c_str());
    sprintf(ota_info_str, 
        "%s<br>ElegantOTA is at <a href=\"http://%s/update\">http://%s/update</a><br>WebSerial is at http://%s:81/webserial", 
        TITLE,
        our_ip_address,
        our_ip_address, 
        our_ip_address);
    request->send(200, "text/html", ota_info_str);
});

This works.

I tried to put the allocation of “ota_info_str” & “our_ip_address” outside/above the ‘server.on’, but I get an error…

error: ‘ota_info_str’ is not captured

What is going on here?

Ideally, I’d like not only the character arrays allocated earlier, but the 2 sprintf’s also outside the server.on( part.

Thanks, Mark.

1 Like

When you have a lambda function expression like

Then that lambda expression only has access the variables either created inside the lambda expression or explicitly captured. The “capture” part is the [] part, which is currently empty. So, no outside variables are captured. See

for a list of possible captures.

Note that this is especially tricky. The server.on() function just registers a callback function. This function may be called at any time later when there is a request. It would be fatal to register a function in setup() that captures a pointer or a buffer by reference that is not valid anymore once the setup() function is left. Once setup() exits, all its local variables get destroyed. So think very carefully if you want to take anything by copy ([=]) or reference ([&]).

For your function, I would do the following:

  • Get rid of our_ip_address completely. Just insert the expression WiFi.localIP().toString().c_str() as an argument to the format string when you need it
  • Allocate the ota_info_str buffer globally, that means outside of any function. Thus, it will be valid to be used anywhere and you don’t take of space on the stack of the function
  • use buffer-overflow safe functions for printing / string formatting. sprintf() doesn’t know how big the ota_info_str buffer is, so if the formatted string exceeds that length, it won’t know, and cause a buffer overflow. Use snprintf() instead that can take sizeof(ota_info_str) as the maximum length.