Go Down

Topic: sanity check on C++ library and attachInterrupt (Read 875 times) previous topic - next topic

pschimpf

Hoping someone will sanity check an approach I'm using for writing a library. First, I discovered by trial and error (and have seen some similar posts) that using C++ is least troublesome for writing library modules.  I tried doing it in C (.c files) first and got some errors.  So I rewrote the library in C++ and it works seamlessly ...

except for the following little hiccup.  My library needs to install an interrupt service routine using attachInterrupt().  I also discovered, not too surprisingly, that the function pointer passed to attachInterrupt() must use C linkage.   So I used extern "C" for the ISR function and put everything else in a class.  It thus seems I cannot avoid using .cpp files and extern "C" when putting an ISR in a library module.  Seems to me it would make more sense to simply use .c files but that didn't work for me for the regular function calls.

This is a bit confusing, because while .pde code is written in C style, it appears that it uses C++ linkage (why else would I have trouble calling C functions but not C++ member functions?). On the other hand I can put an ISR in a .pde file no problem.  Does the Arduino preprocessor
realize that arguments to attachInterrupt must be C-style and automatically attach extern "C" to their declarations before passing the code onto the gpp compiler, but only if that ISR function appears in a .pde file (iow, it leaves library files untouched)? 

PaulS

Quote
This is a bit confusing, because while .pde code is written in C style, it appears that it uses C++ linkage

Your .pde file is transformed into a .cpp file before the C++ compiler is invoked. So, it is not surprising that C++ linkage is used.

Quote
I tried doing it in C (.c files) first and got some errors.

It could be done in a .c file, if you use the extern "C" modifier appropriately. Using the .cpp extension is just easier.

Quote
I also discovered, not too surprisingly, that the function pointer passed to attachInterrupt() must use C linkage.

Not true. It must be not be a member function, though.

pschimpf

Ah, thanks Paul.  I took the extern "C" off my ISRs and it still works.  That solves the mystery
for me.  Duh, I don't know why I jumped all the way to C linkage instead of just to a global
function when I got the error installing the ISR.  I'm about to post another question about
interrupts, maybe you can answer that one too!  :-)

Go Up