作者QQ29 (我愛阿蓉)
看板C_and_CPP
標題[問題] 指標的轉型問題
時間Thu Feb 9 17:28:26 2012
大家好, 最近在研究一個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
→ 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
→ xatier:的確我想到樓上提到的文章XD 02/10 12:46
→ angleevil:基本上就像tropical72所說那樣,期待大師回一篇好文 02/10 13:38