0
votes

I'm setting up and environment with the gcc-arm-none-eabi toolchain (currently 7.2.1). This is for an ARM cortex M4 embedded device.

I'd like to redefine printf for the entire project, but I'm having trouble. I want to use this implementation. I've installed this into the project, and I can use it by calling, for example: printf_("Test: %i",5); and everything works as expected.

Now I want to set it as the default printf function. If I uncomment: #define printf printf_, I get the following error:

/home/timv/.platformio/packages/[email protected]/arm-none-eabi/include/c++/7.2.1/cstdio:127:11: error: '::printf' has not been declared
   using ::printf;

later on:

src/LoggerTask.cpp:62:5: error: 'printf' was not declared in this scope

In that file I found this line:

#undef printf

When I comment that line out, the project builds, and printf works. This is good, but I would like to have my project function without patching the toolchain.

How should I go about doing this? What other information would be helpful?

2
Do you need a C solution or just a C++ one?Andrew Henle
Why would you #undef printf in your LoggerTask.cpp? f I uncomment: #define printf printf_ - in which file is that define located?KamilCuk
It is a bad idea to redefine standard C names (confusing, and could be undefined behavior). Can't you use myprintf instead in your source code?Basile Starynkevitch

2 Answers

1
votes

You can create a pointer to printf using the next example. You need to create helper files (named "printf_helper.h" and "printf_helper.cpp" in this example). And include "printf_helper.h" (better after all other included headers) to a file where you want to use printf.

printf_helper.h:

#ifndef PRINTF_HELPER_H
#define PRINTF_HELPER_H

namespace helper {
  typedef int (*printf_t) (const char * format, ...);
  extern const printf_t printf_ptr;
}

#endif /* PRINTF_HELPER_H */

printf_helper.cpp:

#include "printf_helper.h"
#include <cstdio>

namespace helper {
  const printf_t printf_ptr = std::printf;
}

Example of usage in main.cpp:

// all other included headers
#include "printf_helper.h"

int main() {
  helper::printf_ptr("Hello, %s!\n", "World");
  return 0;
}
0
votes

Add a new file to your compilation:

#include <stdarg.h>
int vprintf_(const char* format, va_list va);
int printf(const char *str, ...) {
     va_list va;
     va_start(va, str);
     int ret = vprintf_(str, va);
     va_end(va);
     return ret;
}

Compile and link against the resulting object while creating the compilation output. That's all. Because of how linker works, the linker should pick your symbol, instead of the one provided by newlib. Alternatively, you could use --wrap=printf linker option to simply wrap the symbol.