In a recent project I read 4, using polling, on an ATMega328p (much slower than your Pi Pico), using an existing rotary encoder library. So apparently it can be done...
My project did the same, albeit reporting data over I2C on request by a master. It doesn't miss a beat. No interrupts needed for the rotaries.
If you want to have the whole interrupt handling inside your class, you need a function to set the interrupt vector. This depends on the board you are using. For ARM-MC it is defined in the specific header files, e.g. for my Nano BLE 33 it is the function
__NVIC_SetVector((IRQn_Type) x, (dword) irqHandlerStatic)
defined in core_cm4.h (reference in Arduino.h, no need to search).
The function irqHandlerStatic has to be static. From this function you call your instance specific interrupt handlers.
For each instance of the class you have to define a static variable pointing to your instance
className *className::instPtr0 = NULL;
className *className::instPtr1 = NULL;
In your class constructor you load this vector with your class interrupt handler like
instPtr0 = this;
And from your static interrupt handler you call your class interrupt handler with
void class::irqHandlerStatic0()
{
if(instPtr0 == NULL) return;
instPtr0->irqHandler();
}
I think, it makes sense only if you have the same handler (that of your class) for several instances with different interrupt sources. E.g. if You write a universal timer class for all possible timers (5 with Nano BLE 33).
As You have only one interrupt source and only one instance of your class (I suppose), it is more simple to attach an interrupt handler defined in the (let me call it) C-area of your sketch. Make an instance of your class like
ClassName classInst;
and call the interrupt handler of your class from your outside handler with
classInst.intHandler();
Good luck
I like that thought; it would indeed be a solution, although (as I argued above) I personally think it would make more sense to evade the problem altogether.
However, to latch into your train of thought: another possibility is to have one ISR defined in the main sketch, and an update-routine in the class that can be called by the ISR. You could have any (reasonable) number of class instances register with the ISR, much like how you register timer interrupt handlers on e.g. an ESP platform.
In practice this approach works fairly well, but there are platform-specific requirements to take note of (much like in your own proposed solution). For instance, on ESP platforms it requires that the ISR-called routines are stored in IRAM to prevent long jumps in the ISR, which may (or may not...in practice it sometimes works OK) trigger the watchdog and cause a kernel panic. I don't know what the caveats on Pi Pico would be, but there are likely to be some. Hence my recommendation to avoid the problem altogether as in my experience it doesn't compare favorably to the lower complexity of an alternative solution.