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

看板C_and_CPP (C/C++)作者 (asil)時間9年前 (2016/10/12 01:11), 9年前編輯推噓4(404)
留言8則, 2人參與, 最新討論串2/3 (看更多)
該睡了但還沒睡意,用最簡單的方式實作一下 這種做法完全不支援多重繼承,不過應該可以達到原本的需求 ==== 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的情況)? : 請各位賜教。感謝。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.137.193.214 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1476205869.A.A39.html

10/12 02:13, , 1F
你的架構比我想的簡潔一些,感謝。
10/12 02:13, 1F

10/12 02:39, , 2F
不過這樣的作法就是要多加一個能free I2C_Device_ADXL345
10/12 02:39, 2F

10/12 02:40, , 3F
的函式。
10/12 02:40, 3F

10/12 03:54, , 4F
我就是想達到這樣的效果,然後可以把實作跟宣告分開
10/12 03:54, 4F

10/12 06:50, , 5F
free一樣做成func pointer在new時指定即可
10/12 06:50, 5F

10/12 14:51, , 6F
不行吧?這樣不是free掉自己?
10/12 14:51, 6F

10/12 19:52, , 7F
就和data_fun一樣的方式,然後通通用I2CDevFreeFn解構
10/12 19:52, 7F

10/12 20:07, , 8F
我懂了 感謝
10/12 20:07, 8F
※ 編輯: asilzheng (114.36.115.215), 10/12/2016 21:10:44
文章代碼(AID): #1N_Hqjev (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1N_Hqjev (C_and_CPP)