logo elektroda
logo elektroda
X
logo elektroda

[ESP07][Arduino][ESPAsyncWebServer] - I can't move functions to their own classes

sq9etc 1224 12
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • #1 18825738
    sq9etc
    Level 12  
    Posts: 228
    Help: 11
    Rate: 15
    Board Language: polish
    When I have all the variables and functions relating to the server in the main.c file it is fine. The program compiles and runs.
    Code: C / C++
    Log in, to see the code
    .

    When the variables t , h and index_html[] and functions processor and initWebServer I will move to my own class, then the program stops compiling.
    The following errors appear in the method WebServer::init :
    Code: Bash
    Log in, to see the code
    .

    The code looks as follows:
    Code: C / C++
    Log in, to see the code
    .

    Code: C / C++
    Log in, to see the code
    .

    Code: C / C++
    Log in, to see the code
    .

    What am I doing wrong?
  • ADVERTISEMENT
  • #2 18825915
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #3 18827162
    sq9etc
    Level 12  
    Posts: 228
    Help: 11
    Rate: 15
    Board Language: polish
    khoam wrote:
    The second and third errors are of the same type. You should use send() instead of send_P():
    .
    Then why does it work send_P() in the non-object version?
  • #4 18827327
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #5 18828565
    sq9etc
    Level 12  
    Posts: 228
    Help: 11
    Rate: 15
    Board Language: polish
    For the first error I converted the function processor to static according to your suggestion. Now I have 2 errors that it does not know t and h .
    For the other two errors I changed the function calls send_P() to send() , but I still get the error 'this' was not captured for this lambda function .
  • #6 18828578
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #7 18828591
    sq9etc
    Level 12  
    Posts: 228
    Help: 11
    Rate: 15
    Board Language: polish
    Code: C / C++
    Log in, to see the code
    .

    Code: Bash
    Log in, to see the code
    .
  • Helpful post
    #8 18828637
    Anonymous
    Level 1  
  • #9 18828650
    sq9etc
    Level 12  
    Posts: 228
    Help: 11
    Rate: 15
    Board Language: polish
    Thanks, that helped.
    I still don't know what to do to make the static function processor see the fields t and h .
    Code: Bash
    Log in, to see the code
    .
  • #10 18828669
    Anonymous
    Level 1  
  • #11 18837265
    sq9etc
    Level 12  
    Posts: 228
    Help: 11
    Rate: 15
    Board Language: polish
    I did as recommended. Now there is this error:
    Code: Bash
    Log in, to see the code
    .

    i.e. again can't match method String WebServer::processor(const String& var) as parameter of function send_P .
  • Helpful post
    #12 18837431
    Anonymous
    Level 1  
  • #13 18838169
    sq9etc
    Level 12  
    Posts: 228
    Help: 11
    Rate: 15
    Board Language: polish
    Thanks, you are great. Now it compiles and even works:) .

Topic summary

✨ The discussion revolves around issues faced when attempting to refactor an Arduino project using the ESPAsyncWebServer library by moving functions into their own classes. The user initially encounters compilation errors related to function type mismatches and variable scope, particularly with the static function `processor` not being able to access instance variables `t` and `h`. Solutions proposed include making the `processor` function non-static and using lambda functions to capture the necessary variables. Ultimately, the user successfully resolves the issues and achieves a working implementation.
Generated by the language model.

FAQ

TL;DR: The 4th parameter of send_P must be AwsTemplateProcessor; “You should use send() instead of send_P()” for String responses. [Elektroda, khoam, post #18825915]

Why it matters: This helps Arduino/ESPAsyncWebServer users moving route handlers into classes avoid lambda-capture and callback-type errors.

Quick Facts

How do I fix “no matching function for call to send_P(..., processor)” after moving handlers into a class?

send_P expects an AwsTemplateProcessor as its fourth parameter. A class member function does not match that free-callable signature. Define an AwsTemplateProcessor variable bound to a lambda that calls your member processor. Pass that lambda to send_P along with your PROGMEM HTML. Keep processor non-static so it can read t and h. This resolves the unresolved overloaded function type error. [Elektroda, khoam, post #18837431]

Why do I get “this was not captured for this lambda function” in my route handlers?

Your lambda does not capture the current object, so member fields like t and h are out of scope. Capture by reference using [&] before the parameter list in each server.on handler. After adding [&], you can access members inside the lambda body safely. The provided example uses [&] with send() to return String(t) and String(h). [Elektroda, khoam, post #18828637]

When should I use send() vs send_P() in ESPAsyncWebServer?

Use send() when sending dynamic String content at runtime. Use send_P() when serving PROGMEM content and optionally applying a template processor. The library exposes both signatures for these cases. As the expert wrote, “send_P() could only be used ... if the third argument were of type PGM_P.” Match your payload to the correct function to avoid type errors. [Elektroda, khoam, post #18825915]

How can I pass a class member as the template processor to send_P?

Create an AwsTemplateProcessor named procfun and assign it a lambda that captures your object and calls processor(s). Then call request->send_P(200, "text/html", index_html, procfun). This makes placeholder replacements like %TEMPERATURE% use your member variables through processor. Keep processor non-static to access t and h directly. [Elektroda, khoam, post #18837431]

Why did making processor static stop it from seeing t and h?

Static methods cannot access non-static fields because they lack a this pointer. Either convert t and h to static too or pass a reference to the object. The recommended path is to revert processor to a non-static member and then provide a matching AwsTemplateProcessor wrapper. [Elektroda, khoam, post #18828669]

How do I move handlers into a class without compile errors? (3-step How-To)

  1. Add [&] capture to every server.on handler lambda.
  2. Keep processor non-static; define AwsTemplateProcessor procfun that calls processor.
  3. Call request->send_P(..., index_html, procfun) for the template route. These steps align handler callbacks with expected types and allow member access. [Elektroda, khoam, post #18837431]

Why did the sketch compile in main.cpp but fail after moving code into a class?

Global functions and variables matched the callback types as free callables. Inside a class, member methods change type and no longer match AwsTemplateProcessor. Also, handlers need to capture context to access members. Adjust by using send() for Strings and wrapping processor for send_P. [Elektroda, khoam, post #18825915]

How do I expose /temperature and /humidity endpoints correctly from a class?

Register routes with lambdas that capture [&]. In each handler, call request->send(200, "text/plain", String(t)) and similarly for h. This avoids c_str() and ensures the lambda can access member fields. The example demonstrates this pattern for both endpoints. [Elektroda, khoam, post #18828637]

How big is the HTML template in this example, and does that impact anything?

The compiler log shows index_html as char[1744], about 1.7 KB. It is declared with PROGMEM in the code. Larger templates increase code storage, so watch flash usage and keep templates efficient. The size noted comes from the error message and declaration context. [Elektroda, sq9etc, post #18837265]

How should I schedule sensor updates without blocking the web server?

Use a millis()-based timer and update every 10 seconds. Store previousMillis and compare with the configured interval. This non-blocking pattern prevents delays in HTTP handling. The example reads temperature and humidity when the interval elapses. [Elektroda, sq9etc, post #18825738]

What exactly is AwsTemplateProcessor?

It is typedef std::function<String(const String&)> from ESPAsyncWebServer. The callback receives a placeholder name and returns a String. Free functions or lambdas match directly. Member functions require a wrapper or must be static to match. [Elektroda, khoam, post #18825915]

How do I resolve “unresolved overloaded function type” for the processor callback?

Define an AwsTemplateProcessor variable bound to a lambda that captures [&] and forwards to processor(s). Pass that variable as the fourth argument to send_P with your PROGMEM HTML. This matches the expected callback type and compiles cleanly. [Elektroda, khoam, post #18837431]

I switched to send(), but I still see 'this was not captured'—what’s left to change?

send() fixes the content-type mismatch, not the scope issue. Add [&] before the lambda parameter list to capture the object context. Then send with String(t) and String(h) inside the captured lambdas. This resolves the capture error. [Elektroda, khoam, post #18828637]
Generated by the language model.
ADVERTISEMENT