看板 C_and_CPP 關於我們 聯絡資訊
大家好, 最近在研究一個API, 雖然成功使用 卻不解他的設計方式.... http://msdn.microsoft.com/en-us/library/ms919833.aspx 他最後 PBT_POWERINFOCHANGE 這個case會傳一個structure如下 http://msdn.microsoft.com/en-us/library/ms919667.aspx 他Remark 部分有寫到 The POWER_BROADCAST structure has a variable length. The SystemPowerState array is a placeholder for data associated with the message being broadcast and is not always WCHAR data. 這邊我就覺得很不解 如果是我自己寫 該怎麼做一個會變動長度的structure 於是我去google一下他該怎麼轉型, 因為MSDN也沒範例程式 http://tinyurl.com/7h26s88 PPOWER_BROADCAST_POWER_INFO ppbpi = (PPOWER_BROADCAST_POWER_INFO) &pbb.SystemPowerState[0]; 他就直接把第四個field轉成他所說的型態 結果確實可以work 於是我去意測他的作法 struct _POWER_BROADCAST_REAL { DWORD Message; DWORD Flags; DWORD Length; VOID* ptr; }; //我猜他實際上是new這個型態 struct _POWER_BROADCAST { DWORD Message; DWORD Flags; DWORD Length; WCHAR ptr[1]; }; struct _POWER_BROADCAST_POWER_INFO { int data; }; int main() { _POWER_BROADCAST_POWER_INFO Data; Data.data = 5566; _POWER_BROADCAST_REAL* realObject = (_POWER_BROADCAST_REAL*)malloc(sizeof(_POWER_BROADCAST_REAL)); realObject->Message = 7788; realObject->Length = 123; realObject->ptr = &Data; //指到實際的物件 // _POWER_BROADCAST* fakeType = (_POWER_BROADCAST*)realObject; //先印出message, 成功 cout<<fakeType->Message<<endl; //學 網路上都這種寫法 _POWER_BROADCAST_POWER_INFO* ptr2 =     (_POWER_BROADCAST_POWER_INFO*)fakeType->ptr; //印出怪值 cout<<ptr2->data; } 我大概知道為啥我會印出怪值 因為我_POWER_BROADCAST::ptr 是一個static array 他似乎就直接得到 fakeType->Length address + 4 所以我必須改成 轉型兩次 _POWER_BROADCAST_POWER_INFO *ptr2 = (_POWER_BROADCAST_POWER_INFO *)(((_POWER_BROADCAST*)fakeType)->ptr); cout<<ptr2->data<<endl; 這樣才會得到正確值~~ 令我不解的就是 為啥MSDN的這種用法 直接轉型沒有後顧之憂 如果是我猜測錯誤 那還有什麼做法能夠 達成他的可變動長度... 實在是不解 煩請各位給予指正 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 219.87.64.222
james732:大概只有這樣而已 http://ideone.com/XIzAT 02/09 17:39
Favonia:可參考 gcc.gnu.org/onlinedocs/gcc/Zero-Length.htm 02/09 19:19
QQ29:簡單講就是在malloc的空間區段內 怎麼解釋這塊記憶體都OK嚕? 02/09 23:56
james732:是啊,一開始拿大一點的空間,多出來的都隨便你用 02/10 00:05
angleevil:WCHAR ptr[1];<-c99允許structure的最後一個成員為未定 02/10 09:58
angleevil:大小的陣列.可以根據malloc去配置最後一個成員的大小 02/10 09:59
james732:樓上大師可以回覆一篇文章嗎 XDDD 02/10 10:01
angleevil:超哥...不是會了嘛? 02/10 10:03
angleevil:我猜可變動的原因在WCHAR ptr[1];<-其實按照c99的標準 02/10 10:21
angleevil:應該要是WCHAR ptr[]; 只是我在gcc會看[0],vc會看到[1] 02/10 10:22
angleevil:Favonia已經點出來這點了!只是有錯的話,請大家糾正了喔 02/10 10:24
tropical72:#1DhhMrOO (C_and_CPP) 是否有異曲同工之妙? 02/10 11:22
xatier:的確我想到樓上提到的文章XD 02/10 12:46
angleevil:基本上就像tropical72所說那樣,期待大師回一篇好文 02/10 13:38