Я пишу приложение C ++ поверх C HAL для встроенных систем. Мне нужно вызвать метод объекта из периферийного обработчика C, но у меня возникла следующая проблема:
Периферийный обработчик ISR, который я передаю в HAL, имеет фиксированную подпись. Из-за этого я не могу передать открытый метод объекта C ++ из-за неявного параметра this. В обработчике у меня нет никакой ссылки на объект.
Одним из решений может быть сделать этот объект синглтоном, чтобы иметь глобальный доступ к нему, но по любой причине я могу не захотеть этого.
Что я могу сделать?
Простая функция-член C ++ никогда не может быть ISR. Это должно быть static
функция-член. На самом деле вы должны сделать что-то вроде дизайна синглтона. Нет необходимости делать что-то «глобальным».
Это не уникально для ISR, но то же самое относится к любой функции обратного вызова.
Моя первая мысль — иметь переменную указателя метода, которую можно установить, и ISR вызывает этот указатель метода, если он установлен.
Это непроверенный, не скомпилированный код, но он показывает, как мне начать:
void (*Object::Method)() IsrMethod;
// call this to set the method that will be called. Maybe pass
// in the method pointer of a specific object.
void SetIsrMethod()
{
IsrMethod= someObject.someMethod;
}
void ISR()
{
// if the method is valid, call it.
if( IsrMethod!= null )
{
IsrMethod();
}
}
Это также предполагает, что объект действителен и не удален.
Class MyObj
{
public:
void doIsr()
{
// Handle ISR.
}
static void HandleIsr()
{
MyObj* isrObj = getRelevantObject(); // Whatever object you like to call to.
isrObj.doIsr();
}
}
Если вы хотите зарегистрировать определенный объект в isr, вы можете сделать это следующим образом:
Class MyObj
{
public:
void doIsr()
{
// Handle ISR.
}
static void HandleIsr(MyObj* obj)
{
obj.doIsr();
}
}
И когда вы регистрируетесь на ISR, вам необходимо пройти obj
в качестве параметра.