jeudi 2 mars 2023

How must a function pointer be defined, which points to a function with variadic arguments

The goal is to have logging, both under Arduino / espressif platform and native. C++ 11 is used.

For example:

logx("Text val1: %d, val2: %u", a, 123);
------> 20:24:27.237 > [    26][D][main-log3.cpp:60] setup(): Text val1: 2, val2: 123

The PlatformIO supports Unit Tests (UT). The UT are executed in the so-called native mode, i.e. here is no Arduino framework available, which makes sense. Thus the Arduino / espressif logging does not work. However, the following approach should enable logging both in the case of a deployement and in the case of UT. There are two logging functions, one for native mode and one for deployment, in different files of course. The log functionality is defined with the following macro:

#define logx(format, ...) logStruct.loggerCb(ARDUHAL_LOG_FORMAT(X, format), ##__VA_ARGS__)

There is a structure with a function pointer, which points to one of the two logging functions (nativeLogger, arduinoLogger) refers.

template <typename... Args>
using logging_t = void(const char *, Args &&...args);

template <typename... Args>
struct LogStruct_t {
    logging_t<Args> *loggerCb;
};

The plan is, either in a macro (preferred) or in the setup routine, to place the appropriate logging function at the function pointer to assign.

I've been trying for hours now to define a function pointer passed a function with variadic arguments can be.

Here is my code with the corresponding error message, marked with ===========

How must the pointer and the two functions be defined. Many thanks for the help

#include <Arduino.h>
#include <esp32-hal-uart.h>
#include <stdarg.h>

/* ---------------------------------------------------------
 * Defines
 --------------------------------------------------------- */

#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
#ifndef USE_ESP_IDF_LOG
#define logx(format, ...) logStruct.loggerCb(ARDUHAL_LOG_FORMAT(X, format), ##__VA_ARGS__)
#endif  //................^ 'logStruct' was not declared in this scope ======================
#endif

/* ---------------------------------------------------------
 * Type Definitions
 --------------------------------------------------------- */

template <typename... Args>
using logging_t = void(const char *, Args &&...args);

template <typename... Args>
struct LogStruct_t {
    logging_t<Args> *loggerCb;
};  //...............^parameter packs not expanded with '...': ======================

/* ---------------------------------------------------------
 * Static Function / Prototypes
 --------------------------------------------------------- */

template <typename... Args>
LogStruct_t<Args> logStruct;
// .........^ parameter pack "Args" was referenced but not expanded  ======================
// ...............^ "logStruct" is not a function or static data member  ======================

template <typename... Args>
static void nativeLogger(const char *format, ...) {
    va_list args;
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
}

template <typename... Args>
static void arduinoLogger(const char *format, Args &&...args) {
    log_printf(format, args...);
}

void setup() {
    // put either nativeLogger or arduinoLogger
    logStruct.loggerCb = nativeLogger;
    //..^ identifier "logStruct" is undefined  ======================
    logStruct.loggerCb = arduinoLogger;
    //
    int a = 2;
    logx("Text val1: %d, val2: %u", a, 123);
    //.^ identifier "ARDUHAL_LOG_COLOR_X" is undefined  ======================
}

void loop() {
    // put your main code here, to run repeatedly:
}

/*===================================================================================
Output

=====================================================================================
*/

Aucun commentaire:

Enregistrer un commentaire