How to wrap an existing library in a custom namespace to avoid redeclaration error?

Dear community,

I have a namespace related issue, which I am unable to solve, even with Dr. Google, as I am not familiar with namespaces at all.

With my latest project, I would like to use the following two libraries (installed latest version via library manager) in a sketch running on an Arduino Nano:

  • INA219_WE (voltage and current sensor readout)
  • Low-Power (save some power in between sensor readouts)

Both libraries work well independently.

However, if I import both libraries in the same sketch, I get a redeclaration error:

Sketch

#include <INA219_WE.h>
#include <LowPower.h>

void setup() {
}

void loop() {
}

Error

In file included from <...>\libraryConflictExample\libraryConflictExample.ino:2:0:
<...>\Arduino\libraries\Low-Power/LowPower.h:29:2: error: redeclaration of 'ADC_OFF'
  ADC_OFF,
  ^~~~~~~
In file included from <...>\libraryConflictExample\libraryConflictExample.ino:1:0:
<...>\Arduino\libraries\INA219_WE\src/INA219_WE.h:59:5: note: previous declaration 'INA219_MEASURE_MODE ADC_OFF'
     ADC_OFF         = 0b00000100,
     ^~~~~~~

As the error message indicates, both libraries use the constant ADC_OFF. A similar problem was discussed for different libraries. There, the author fixed the problem by modifying one of the libraries. For compatibility reasons I would like to avoid changing the (external) library code.

In the aforementioned thread @PieterP suggested to "wrap all library code in a namespace".

So what I tried is this:

#include <INA219_WE.h>
namespace LoPo {
  #include <LowPower.h>
}

void setup() {
}

void loop() {
  LoPo::LowPower.idle(LoPo::SLEEP_8S, LoPo::ADC_OFF, LoPo::TIMER2_OFF, LoPo::TIMER1_OFF, LoPo::TIMER0_OFF, 
                      LoPo::SPI_OFF, LoPo::USART0_OFF, LoPo::TWI_OFF);
}

For the library import this works fine, but the function call raises an error:

<...>\AppData\Local\Temp\ccbloPUo.ltrans0.ltrans.o: In function `loop':
<...>\Arduino\libraryConflictExample/libraryConflictExample.ino:10: undefined reference to `LoPo::LowPower'
<...>\Arduino\libraryConflictExample/libraryConflictExample.ino:10: undefined reference to `LoPo::LowPower'
<...>\Arduino\libraryConflictExample/libraryConflictExample.ino:10: undefined reference to `LoPo::LowPowerClass::idle(LoPo::period_t, LoPo::adc_t, LoPo::timer2_t, LoPo::timer1_t, LoPo::timer0_t, LoPo::spi_t, LoPo::usart0_t, LoPo::twi_t)'
collect2.exe: error: ld returned 1 exit status

Hence, I was wondering: Is it possible to wrap the entire contents of a library including function calls in a namespace without touching the external library code? And if yes, how would I do this?

Any help would be appreciated,
Max

As a new user I am apparently not allowed to add more than two links in a post (weird restriction).
Hence, here the links to the library codes:

  • INA219_WE (voltage and current sensor readout)
  • Low-Power (save some power in between sensor readouts)

That's not what I meant, you need to edit the library source files and add the namespaces there, wrapping the header won't work.

Did you try the enum class solution I mentioned in the other thread?

Wow, that was quick!

Based on your answer I now tried to change the LowPower.h: (Is this what you meant?)
old

enum adc_t
{
	ADC_OFF,
	ADC_ON
};

new

enum class adc_t
{
	ADC_OFF,
	ADC_ON
};

Sketch

#include <INA219_WE.h>
#include <LowPower.h>

void setup() {
}

void loop() {
  LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, 
                      SPI_OFF, USART0_OFF, TWI_OFF);
}

This results in a conversion error:

no known conversion for argument 2 from 'INA219_MEASURE_MODE' to 'adc_t'

Hence, I suspect I have to use ADC_OFF differently in the function call. Can you help?

I was still hoping for a solution without touching the library code, if there is any. Otherwise, I could simply rename the constant in one of the libraries.

EDIT:
OK, it seems I have to change it to adc_t::ADC_OFF
Unfortunately this results in multiple 'ADC_OFF' was not declared in this scope errors. I suspect this is because the author of LowPower.h does not actually assign values to the library's constants. At least I was not able to find any in the git repo. -> I will try editing the other library instead.

You have to change this in the library itself as well.
Assigning values is not necessary.

OK, thanks for the help.

Remains the question: Is there any way (maybe not namespace but a different approach), which could leave the external libraries untouched?

Another option is to not use the low power library , and use Google to find the code to put your device to sleep without it .

1 Like