2016-10-03 57 views
0

我正在爲運行在stm32上的嵌入式應用程序開發可視化調試器。 因此,調試器將在PC上運行,重複使用與主應用程序相同的代碼,但觸發硬件反應的低級功能除外,並且將爲GUI(QT)發送信號。創建一個類的多個實現,一個發送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,它不能因爲這部分有沒有Qt的世界的線索,在使用時,GpioWrapper.h的情況下嵌入式應用程序,如果可能的話,我想避免在我的包裝中使用#ifdef #else。

什麼可能是更清潔的方式來解決?

+0

一般建議是儘量避免混用GUI和應用程序算法。雖然如果您在嵌入式系統中擁有基類,那麼可以通過GPIO驅動程序和GUI同時繼承該基類。在一種情況下,它切換實際的I/O引腳,在另一種情況下,它顯示一些奇特的東西。 – Lundin

+0

確切地說,我想要的是,只有低級別的函數被覆蓋,所有的應用程序邏輯保持不變。所以,是的,正如@ Chajnik-U提出的,我將用一種抽象類來實現兩種不同的方式和一種靜態方法來檢索正確的實現。 –

回答

0

你可以讓你GpioWrapper抽象類,並將其放置於頭文件,並有兩個CPP文件與STM和QT的情況下實現每個包括相應的項目

文件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的<>或通過新的甚至是動態分配的(這裏只是想說明的想法) 。我們可以聲明靜態的GpioWrapper * Instance()方法,它將poiner返回靜態分配的實例等等(但要注意所謂的Meyers單例 - 對於一些舊的編譯器來說它不是線程安全的)。

+0

我會嘗試你的解決方案,靜態創建功能是我正在尋找的缺失部分,但我會去一個thread_local實例,因爲該方法中的「新」隱藏在我看來是內存泄漏的開放門戶。謝謝您的幫助 :) –

0

如果你想避免使用QObject,你可以通過在C++(11)中使用function callback來實現你的uwn SIGNAL/SLOT結構,使用lambda函數。

這是實現某些事件的呼叫者通知的替代方案。

標準算法庫的許多函數都使用回調函數。

+0

當調用者知道他需要使用泛型方法時,我確實使用了lambda表達式,但這是另一種方式,調用者對通過調用setRelayState函數觸發的內容一無所知。所以我真的不明白我在這裏如何使用lambdas。 關於回調,我從來沒有真正使用它們,所以鏈接提供了一個很好的解釋,但是再次說明,對於調用者提供實際邏輯而不是其他方式的泛型方法,它似乎更加有用。我對嗎? –

相關問題