Search code examples
c++arduinoesp8266

What is the correct way to create a class function that is passed a string array as a parameter? [Arduino]


I want to create my own function in an existing library from Arduino/ESP8266, pass an empty array in case the user doesn't have any header.

//.h file
t_httpUpdate_return updateheader(WiFiClient& client, const String& url, const String& currentVersion = "", const String& header[][2] = {{}});

//.cpp file
HTTPUpdateResult ESP8266HTTPUpdate::updateheader(WiFiClient& client, const String& url, const String& currentVersion, const String& header[][2])
{
    HTTPClient http;
    http.begin(client,url);
    for (int i, i < sizeof(header), i++){
        http.addHeader(F(header[i][0]), header[i][1]);
    }
    return handleUpdate(http, currentVersion, false);
}

But I get the next error when I try to compiling:

C:\Users\myuser\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266httpUpdate\src/ESP8266httpUpdate.h:125:143: error: declaration of 'header' as array of references
    
t_httpUpdate_return updateheader(WiFiClient& client, const String& url, const String& currentVersion = "", const String& header[][2] = {{}});
    
                                                                                                                                        ^
    
exit status 1
    Error compilando para la tarjeta NodeMCU 1.0 (ESP-12E Module).

I'm using ESP8266httpUpdate Library.


Solution

  • Arrays of references are not allowed. Also, you can't constrain the size of the inner array like that.

    Arrays can't be passed around as values, they basically decay to pointers when you pass them to another function. That also means you need to pass along the size of the array.

    What you wrote: sizeof(header) is a bug - you got a C-style array as a function argument, the array decays to a pointer and sizeof(header) gives you the size of a pointer and not the length of the array!

    I'd use a struct for the actual header, since you always want a size of 2 and then you only have to deal with a one-dimensional array:

    struct HttpHeader {
        String name;
        String value;
    };
    
    t_httpUpdate_return updateheader(WiFiClient& client, const String& url,
            const String& currentVersion = "",
            const HttpHeader* headers, int headers_size)
    {
        HTTPClient http;
        http.begin(client,url);
    
        for (int i = 0; i < headers_size; i++) {
            http.addHeader(F(headers[i].name), headers[i].value);
        }
    
        return handleUpdate(http, currentVersion, false);
    }
    
    // Calling it somewhere:
    HttpHeader headers[] = { { String("Accept"), String("application/json") } };
    updateheader(client, version, headers, 1);
    

    Note that this means the array data lives in the stack of the calling function and the pointer becomes invalid once that function ends. But that's always the case when not using heap allocation.