创建一个类的多个实现,一个用于发送Qt信号,另一个用于直接使用硬件
create multiple implementations of a class, one to send Qt signals and one to work with hardware directly
我正在为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函数。
这是实现某些事件的调用者通知的另一种选择。
标准算法库中的许多函数都使用回调函数
- 如何巧妙地编写两个函数——一个用于检查是否存在解决方案,另一个用于获取所有解决方案
- 我如何创建一个列表,然后从中创建两个列表,其中一个用于偶数,另一个用于奇数?
- C++设置了一个用于排序的比较器和另一个用于唯一性的比较器
- 我应该有 2 个单独的班级,一个用于"logic",一个用于"graphic interface"?
- 为什么T是未定义的?我正在尝试实现一个用于双链表的节点类,它不喜欢我使用友元运算符后的T
- 如何使用 Turbo C++并行运行两个功能,一个用于键盘,一个用于鼠标?
- C++构造函数,一个用于度,一个用于弧度
- 维护/维持两个代码集的风险,一个用于 CPU,一个用于 GPU,需要执行非常相似的功能
- C 两个线程一个用于输入,一个用于输出
- 一个用于保存模板专业参数的结构
- 实现了一个用于rsa加密的bignum库
- 编译三个文件以创建一个用于平均值的程序(取消注释?)
- 创建一个用于使用多个数据库的c++文件
- 一个用于操作字符串以在vba中使用的c++dll
- 调用一个用于内存分配的方法c++
- 一个用于处理字符* 和 wchar_t* 的函数
- 如何在 OSX 上创建一个用于C++的窗口
- 寻找一个用于信号处理的良好的C/C++小波库
- 在QT中,是否有一个用于double、float、int等的动态数组.即QDoubleArray
- 对于 C++11,我是否仍然需要一个用于 Unicode 文本的非标准字符串操作库