1. 程式人生 > 其它 >C語言利用結構體封裝函式API

C語言利用結構體封裝函式API

技術標籤:C語言C51/C52STM32

結構體簡述

C語言結構體(Struct)從本質上講是一種自定義的資料型別,只不過這種資料型別比較複雜,是由 int、char、float 等基本型別組成的。例如,在校學生有姓名、年齡、身高、成績等屬性,學了結構體後,我們就不需要再定義多個變量了,將它們都放到結構體中即可,如圖所示:
在這裡插入圖片描述

API封裝方法

那麼我們怎麼用C語言的結構體來封裝函式API呢?
首先看看C++和C的區別及方法:

C++類

C++語言類中可以封裝函式,體現了模組操做的整體性,下面程式碼便是C++語言對某個函式的封裝,這樣操作便於呼叫。

lass MarlinSerial //: public Stream
{ public: MarlinSerial(); void begin(long); void end(); int peek(void); int read(void); void flush(void); }

呼叫方法:

MarlinSerial MSerial; //例項化一個物件
MSerial.begin(9600);//設定串列埠的波特率為9600

這樣便對對串列埠操作函式進行了模組化封裝,程式碼結構清晰。

C語言結構體

那麼C語言是否可以實現這種方式呢?C語言結構體不能直接封裝函式,但可以通過封裝函式指標的方式來實現,具體方法如下:
首先看看結構體的基本使用及定義方法,也就是上面所說的定義不同的資料型別,如下所示:

typedef struct
{
    uint8_t     uart1;
    uint32_t    uart2;
    uint8_t     uart3;
    uint8_t     uart4;
    
    uint16_t     channel;
    
}serial_t;

函式封裝方法如下,首先比如我們有如下幾個函式

void hs_register_usart_callback(uint8_t usart_x,void (*ptr)(uint8_t*,uint16_t),uint16_t BuffSize,uint8_t reMode);
void usart_config
(uint8_t usart_x,uint32_t baud_rate); void hs_usart_printf(uint8_t usart_x, const char *Data,...); void hs_usart_sendHex(uint8_t usart_x,uint8_t *data,uint16_t len);

那麼要想封裝這結果函式,結構體封裝就如下所示(其中函式指標名稱可自定義):

ypedef struct
{
    uint8_t uart1;
    uint8_t uart2;
    uint8_t uart3;
    uint8_t uart4;
    uint8_t channel;//自定義資料
    
    void (*config)(uint8_t usart_x,uint32_t baud_rate);
    void (*register_callback)(uint8_t usart_x,void (*ptr)(uint8_t*,uint16_t),uint16_t BuffSize,uint8_t reMode);
    void (*print)(uint8_t usart_x, const char *Data,...);
    void (*sendHex)(uint8_t usart_x,uint8_t *data,uint16_t len)}serial_t;/*API 操作結構體*/

然後申明一下就可以用了,如下:

serial_t serial;

然後在名稱後面加一點就可以呼叫對應的函數了。如下圖所示:
在這裡插入圖片描述
如果想進一步封裝,也可以這樣,但是使用方法都是是一樣的。

/*API 函式初始化*/
serial_t serial =
{
    .uart1 = 0,
    .uart2 = 1,
    .uart3 = 2,
    .uart4 = 3,
    .config = usart_config,
    .register_callback = hs_register_usart_callback,
    .print = hs_usart_printf,
    .sendHex = hs_usart_sendHex,
};