wtorek, 18 września 2018

C - Implementacja struktury z wskaźnikami do funkcji

W tym poście chciałbym przedstawić sposób wykonania struktury z wskaźnikami do funkcji. Dzięki temu będzie możliwe wywołanie funkcji jak i zmiennych przypisanych do danej paczki.

[Źródło: https://icons.com/icon/40670/c-programming]

Za przykład wykorzystam tutaj bibliotekę do obsługi wyświetlacza TFT sterowanego przez UART.

Program:


Poniżej lista przygotowanych funkcji dla wyświetlacza:

  1. void M7Axa_PrintString(const char * str, FontSize_TypeDef fontSize, uint16_t posX, uint16_t posY,
  2.         uint16_t textColor);
  3. void M7Axa_PrintStringWithBg(const char * str, uint16_t len, FontSize_TypeDef fontSize,
  4.         uint16_t posX, uint16_t posY, uint16_t textColor, uint16_t bgColor);
  5. void M7Axa_Disp_DrawCircle(uint16_t Xa, uint16_t Ya, uint16_t R, uint16_t Color);
  6. void M7Axa_Disp_FillInColor(uint16_t Xa, uint16_t Ya, uint16_t Xe, uint16_t Ye, uint16_t Color);
  7. uint8_t M7Axa_ClearScreen(uint16_t bgColor);
  8. void M7Axa_CutPicture(uint16_t Pn, uint16_t Xa, uint16_t Ya, uint16_t Xb, uint16_t Yb, uint16_t Xs, uint16_t Ys);
  9. void M7Axa_DrawDot(uint16_t Xa, uint16_t Ya, uint16_t Color);
  10. void M7Axa_DrawLine(uint16_t Xa, uint16_t Ya, uint16_t Xe, uint16_t Ye, uint16_t Color);
  11. void M7Axa_BacklightControl(uint8_t onOffState);
  12. uint8_t M7Axa_LoadPicById(uint16_t Pn, uint16_t Xa, uint16_t Ya);
  13. void M7Axa_LoadPicture(char * path, uint16_t posX, uint16_t posY);
  14. void M7Axa_DrawRactangle(uint16_t Xa, uint16_t Ya, uint16_t Xb, uint16_t Yb, uint16_t Color);
  15. void M7Axa_GetScreenSize();
  16. void M7Axa_DisplayAlphabeticString(uint16_t Xa, uint16_t Ya, uint16_t Color, const char * str);
  17. uint8_t M7Axa_BuzzerControl(uint16_t Tb, uint16_t Fb);
  18. TPCoords_Typedef getTouchPadData(uint8_t * recBuffer, uint16_t bufferSize);

Dla tych funkcji można przygotować strukturę przechowującą wskaźniki do każdej z tych funkcji:

  1. typedef struct{
  2.     void (*PrintString)(const char * str, FontSize_TypeDef fontSize, uint16_t posX, uint16_t posY, uint16_t textColor);
  3.     void (*PrintStringWithBg)(const char * str, uint16_t len, FontSize_TypeDef fontSize, uint16_t posX, uint16_t posY, uint16_t textColor,uint16_t bgColor);
  4.     void (*Disp_DrawCircle)(uint16_t Xa, uint16_t Ya, uint16_t R, uint16_t Color);
  5.     void (*Disp_FillInColor)(uint16_t Xa, uint16_t Ya, uint16_t Xe, uint16_t Ye, uint16_t Color);
  6.     uint8_t (*ClearScreen)(uint16_t bgColor);
  7.     void (*CutPicture)(uint16_t Pn, uint16_t Xa, uint16_t Ya, uint16_t Xb, uint16_t Yb, uint16_t Xs, uint16_t Ys);
  8.     void (*DrawDot)(uint16_t Xa, uint16_t Ya, uint16_t Color);
  9.     void (*DrawLine)(uint16_t Xa, uint16_t Ya, uint16_t Xe, uint16_t Ye, uint16_t Color);
  10.     void (*BacklightControl)(uint8_t onOffState);
  11.     uint8_t (*LoadPicById)(uint16_t Pn, uint16_t Xa, uint16_t Ya);
  12.     void (*LoadPicture)(char * path, uint16_t posX, uint16_t posY);
  13.     void (*DrawRactangle)(uint16_t Xa, uint16_t Ya, uint16_t Xb, uint16_t Yb, uint16_t Color);
  14.     void (*GetScreenSize)();
  15.     void (*DisplayAlphabeticString)(uint16_t Xa, uint16_t Ya, uint16_t Color, const char * str);
  16.     uint8_t (*BuzzerControl)(uint16_t Tb, uint16_t Fb);
  17.     TPCoords_Typedef (*getTouchPadData)(uint8_t * recBuffer, uint16_t bufferSize);
  18. }TFT_Display_TypedefStruct;

Teraz jej inicjalizacja podanymi wcześniej funkcjami:

  1. TFT_Display_TypedefStruct TFT_Display = {
  2.         M7Axa_PrintString,
  3.         M7Axa_PrintStringWithBg,
  4.         M7Axa_Disp_DrawCircle,
  5.         M7Axa_Disp_FillInColor,
  6.         M7Axa_ClearScreen,
  7.         M7Axa_CutPicture,
  8.         M7Axa_DrawDot,
  9.         M7Axa_DrawLine,
  10.         M7Axa_BacklightControl,
  11.         M7Axa_LoadPicById,
  12.         M7Axa_LoadPicture,
  13.         M7Axa_DrawRactangle,
  14.         M7Axa_GetScreenSize,
  15.         M7Axa_DisplayAlphabeticString,
  16.         M7Axa_BuzzerControl,
  17.         getTouchPadData
  18. };

Aby wywołać poszczególne funkcje należy podać nazwę struktury następnie wskaźnik do funkcji oraz parametry:

  1. TFT_Display.PrintStringWithBg(msg, sizeof(msg), FontSize_48, 40, 20, 0xFFFF, 0x0000);