sanity check on C++ library and attachInterrupt

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)?

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.

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.

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.

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! :-)