创建一个类的多个实现,一个用于发送Qt信号,另一个用于直接使用硬件

create multiple implementations of a class, one to send Qt signals and one to work with hardware directly

本文关键字:一个 用于 另一个 硬件 信号 实现 创建 Qt      更新时间:2023-10-16

我正在为stm32上运行的嵌入式应用程序开发一个可视化调试器。因此,除触发硬件反应的低级函数外,调试器将在PC上运行并重用与主应用程序相同的代码,并将向GUI (QT)发送信号。

我正在寻找一种模式或一些干净的东西,可以允许我在代码中没有大的#ifdef。

举个例子:

我有gpio.h和gpio.c文件与stm32低级的东西(它们是由stmCube半生成的,所以我不能完全改变它们)。

(C code)
void GPIO_set_realy_state(int relay, bool state)
{
    HAL_GPIO_WritePin(port,relay,state?GPIO_PIN_SETGPIO_PIN_RESET);
}

我在它们上面有一个c++包装器(GpioWrapper),每当应用程序需要更改IO状态时,就会调用它

GpioWrapper::setRealyState(int relay, bool state)
{
    GPIO_set_realy_state(relay,state);
}

在PC应用程序中,我希望该包装器的另一个实现或类似的东西将被调用而不是上面的一个来发送信号,而不是调用低级函数使GUI更改图标。

GpioWrapper::setRealyState(int relay, bool state)
{
    emit RelayTriggered(relay,state);
}

我面临的问题是,发送信号,我的类需要从QObject继承,它不能在GpioWrapper.h的情况下,该部分没有Qt世界的线索时,在嵌入式应用程序中使用,我想避免#ifdef #else在我的包装器,如果可能的话。

解决这个问题的更简洁的方法是什么?

您可以使您的GpioWrapper类抽象并将其放在头文件中,并具有两个CPP文件,其中包含STM和QT的实现,以将每个CPP文件包含到相应的项目

文件GpioWrapper.h:

class GpioWrapper{
public:
    static GpioWrapper* Create();
    //...
    virtual void setRealyState(int relay, bool state) = 0;
    //...
};

文件GpioWrapperSTM.cpp(作为STM项目的一部分):

class GpioWrapperSTM: public GpioWrapper{
public:
    //...
    void setRealyState(int relay, bool state) override
    {
        GPIO_set_realy_state(relay,state);
    }
    //...
};
GpioWrapper* GpioWrapper::Create(){
    return new GpioWrapperSTM();
}

文件GpioWrapperQT.cpp(作为QT项目的一部分):

class GpioWrapperQT: public QObject, public GpioWrapper{
public:
    //...
    void setRealyState(int relay, bool state) override
    {
        emit RelayTriggered(relay,state);
    }
    //...
};
GpioWrapper* GpioWrapper::Create(){
    return new GpioWrapperQT();
}

示例在您的应用程序中的某处使用:

std::shared_ptr<GpioWrapper> wrapper = GpioWrapper::Create();
wrapper->setRealyState(10, 20);

注意:实际上不必使用std::shared_ptr<>,甚至不必通过new动态分配(这里只是为了说明这个想法)。可以声明静态GpioWrapper* Instance()方法,返回静态分配实例的指针,等等(但要注意所谓的Meyers singleton -对于一些旧的编译器来说,它不是线程安全的)。

如果你想避免使用QObject,你可以通过使用函数回调来实现你自己的SIGNAL/SLOT架构,在c++(11)中,使用lambda函数。

这是实现某些事件的调用者通知的另一种选择。

标准算法库中的许多函数都使用回调函数

相关文章: