Re: [問題] struct轉型的問題

作者: asilzheng (asil)   2016-10-12 01:11:07
該睡了但還沒睡意,用最簡單的方式實作一下
這種做法完全不支援多重繼承,不過應該可以達到原本的需求
==== I2CDevice.h ====
typedef struct __I2C_Device I2C_Device;
struct __I2C_Device {
int (*init_func)(I2C_Device *dev);
int (*data_func)(I2C_Device *dev);
};
int I2CDevInitFn(I2C_Device *dev);
int I2CDevDataFn(I2C_Device *dev);
==== I2CDevice.c ====
#include "I2CDevice.h"
int I2CDevInitFn(I2C_Device *dev) {
return dev->init_func(dev);
}
int I2CDevDataFn(I2C_Device *dev) {
return dev->data_func(dev);
}
==== I2C_ADXL345.h ====
#include "I2C_Device.h"
typedef struct __I2C_ADXL345 I2C_ADXL345;
I2C_ADXL345 *I2CAdxl345New();
==== I2C_ADXL345.c ====
struct __I2C_ADXL345 {
I2C_Device dev;
int16_t rawData[3];
fload realData[3];
};
static int __Adxl345InitFn(I2C_Device *dev) {
I2C_ADXL345 *adxl345 = (I2C_ADXL345 *)dev;
// TODO: do something
}
static int __Adxl345DataFn(I2C_Device *dev) {
I2C_ADXL345 *adxl345 = (I2C_ADXL345 *)dev;
// TOOD: do something
}
I2C_Device_ADXL345 *I2CDevAdxl345New() {
I2C_ADXL345 *adxl345 = (I2C_ADXL345 *)malloc(sizeof(I2C_ADXL345);
adxl345->dev.init_func = &__Adxl345InitFn;
adxl345->dev.data_func = &__Adxl345DataFn;
}
==== main.c ====
#include "I2C_ADXL345.h"
int main (int argc, char **argv) {
I2C_ADXL345 *adxl345 = I2CDevAdxl345New();
I2CDevInitFn((I2C_Device *)adxl345);
I2CDevDataFn((I2C_Device *)adxl345);
return 0;
}
※ 引述《wtchen (沒有存在感的人)》之銘言:
: (板工以身作則來示範怎麼被電)
: 開發平台(Platform): (Ex: Win10, Linux, ...)
: Raspbien + kernel 4.4
: 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
: gcc 4.9.2-10
: 編譯參數:-Wall -pedantic -O3 -std=gnu11
: 問題(Question):
: 正在研究如何用struct做簡單的物件。
: 我有一個物件 I2C_Device
: typedef struct __I2C_Device {
: int (*init_func)(struct __I2C_Device* dev);
: int (*data_func)(struct __I2C_Device* dev);
: } I2C_Device ;
: 性質是I2C_Device 的物件很多,比如其中一個元件
: typedef struct {
: I2C_Device dev;
: int16_t rawData[3]; // 這兩個元件每一個I2C_Device的物件
: float realData[3]; // 不相同,所以不能包在I2C_Device裡
: } I2C_Device_ADXL345;
: I2C_Device_ADXL345* adxl345
: = (I2C_Device_ADXL345*)malloc(sizeof(I2C_Device_ADXL345));
: 如果我需要用 adxl345->dev.data_func 去修改adxl345->rawData跟realData
: 我可以怎麼寫?
: 例如
: (int16_t*)((I2C_Device*) adxl345+1)[1] = 2 ; // 設定rawData[1];
: (float*)((int16_t*)((I2C_Device*) adxl345+1)+3) = 2 ; // 設定realData[0];
: (可是我怕這種寫法會因為alignment的關係得到不正確的結果)
: 還是有別的更好作法(只能用C的情況)?
: 請各位賜教。感謝。
作者: wtchen (沒有存在感的人)   2016-10-12 02:13:00
你的架構比我想的簡潔一些,感謝。不過這樣的作法就是要多加一個能free I2C_Device_ADXL345的函式。我就是想達到這樣的效果,然後可以把實作跟宣告分開
作者: asilzheng (asil)   2016-10-12 06:50:00
free一樣做成func pointer在new時指定即可
作者: wtchen (沒有存在感的人)   2016-10-12 14:51:00
不行吧?這樣不是free掉自己?
作者: asilzheng (asil)   2016-10-12 19:52:00
就和data_fun一樣的方式,然後通通用I2CDevFreeFn解構
作者: wtchen (沒有存在感的人)   2016-10-12 20:07:00
我懂了 感謝

Links booklink

Contact Us: admin [ a t ] ucptt.com