2013-03-16 64 views
4

我有一個包含幾個函數指針的結構。通用接口在頭文件中生成。功能指針結構使用一次結構調用

頭文件

typedef struct 
{ 
    void (*Start)(void); 
    void (*ByteWrite)(uint8_t *pBuffer);  // Modifies I2C buffer 
    uint8_t (*ByteRead)(uint8_t *pBuffer); 
    void (*ArrayWrite)(uint8_t *pBuffer); 
    uint8_t (*ArrayRead)(uint8_t *pBuffer); 
    bool (*Busy)(void); 
} sI2C_t; 


extern const sI2C_t I2C0; 
extern const sI2C_t I2C1; 
extern const sI2C_t I2C2; 

然後在C文件每個函數指針的被實現爲滿足結構接口。

C語言文件

static void I2C0_Start(void) { ... } 
static void I2C0_ByteWrite(*uint8_t) { ... } 
static uint8_t I2C0_ByteRead(*uint8_t) { ... } 
static void I2C0_ArrayWrite(*uint8_t) { ... } 
static uint8_t I2C_ArrayRead(*uint8_t) { ... } 
static bool I2C_Busy(void) { ... } 

const sI2C I2C0 = 
{ 
    I2C0_Start, 
    I2C0_ByteWrite, 
    I2C0_ByteRead, 
    I2C0_ArrayWrite, 
    I2C0_ArrayRead, 
    I2C0_Busy 
}; 

// Code-block repeated for I2C1, I2C2, etc. (REDUNDANT!) 

這使得它比較容易特定的I2C接口訪問功能:

bool status; 

I2C0.Start(); 
status = I2C1.Busy(); 
... 

雖然函數指針基本上都是針對I2C0相同,I2C1,和I2C2等,我必須分別寫出它們的每個,每新的結構接口。由於這是多餘的,有沒有辦法讓我只實現這些函數指針一次?

+0

這可能是其中一個宏將是一個合理的解決方案的情況之一。也就是說,如果你將'I2C0','I2C1'等作爲變量名,聽起來像是一個數組可能是一個更好的方法? – 2013-03-16 23:57:58

+0

正如'extern const sI2C_t I2C [MAX_NUM];'?這些函數仍然需要爲每個函數定義,是正確的?你能舉一個我如何使用這個宏的例子嗎? – Biff 2013-03-17 00:06:04

+1

[X-Macros](http://stackoverflow.com/questions/6635851/real-world-use-of-x-macros/)來拯救! – 2013-03-17 00:13:05

回答

1

標準解決方案是將結構指針作爲第一個參數傳遞給函數。即而不是:

I2C0.Start(); 

你寫:

I2C0.Start(&I2C0); 

然後,您可以添加一些額外的字段結構,以確定它是哪一個(例如,如果你有固定的硬件地址,對於每個I2C總線上,可能在結構的額外字段中具有硬件地址)。

這是C++類的等價方法。

+0

我確實想過把它作爲指針傳遞,但在我看來,因爲我區分'I2C0/1/2'(例如'I2C0.Start()'或'I2C1.Start()'),它本來是可能隱含地指出它是哪一個。 – Biff 2013-03-19 15:26:46

0

你可以寫一個構造函數。例如:

typedef struct{ 
    int a; 
    char b; 
}example; 

void constructor (example *pointer_to_struct, int a_value, char b_value){ 
    pointer_to_struct->a = a_value; 
    pointer_to_struct->b = b_value; /*remember: if you have strings don't have any 
            assignments, since a string (like any other array) is a pointer to 
            its first element*/ 
} 


int main (void){ 

    example ex_struct; 
    constructor(&ex_struct, 10, 'C'); 

    return 0; 
} 

編輯:您還可以編寫一個函數誰使薩姆斯分配爲您所選類型的每個結構。示例:

void constructor(structure *p){ 
    p->a = 10; 
    p->b = 'C'; 
}