作者: jjhou (jjhou)
標題: 【Serialize 的聯想】
時間: Mon Dec 14 01:05:30 1998
【Serialize 的聯想】
侯俊傑 jjhou@ccca.nctu.edu.tw
1998.12.13 第一次發表於
清大.楓橋驛站(140.114.87.5).電腦書訊版(CompBook)
----------------------------------------------------
Windows GDI 模組支援 DIB(Device Independent Bitmap)繪圖
格式,而 MFC 卻沒有為 DIB 包裝一個好用的 class,這真令人
扼腕(MFC 中只有一個 CBitmap,那是為 Device Dependent Bitmap
而準備的)。
●幸運的是...
幸運的是 David Kruglinski 所著的 <Inside Visual C++ 4.0>
(中譯 <深入 Visual C++ 4.0>,侯俊傑/碁峰)chap10 有一個
好用的 CDib。有檔案讀寫功能,有顯示功能,有調色盤功能。
書中範例程式 Ex10c 只使用了 CDib 的讀檔、顯示兩功能,未示範
其寫檔功能。
●不幸的是...
不幸的是這個 CDib 的寫檔功能有問題,在 cdib.cpp 的 #344 的
CDib::Write() 函式中,有以下動作(書上沒有列表,需自行看光碟
檔案):
TRY {
pFile->Write(LPVOID)&bmfh, sizeof(BITMAPFILEHEADER));
pFile->Write(LPVOID)&m_lpBMIH, nSize);
}
怎麼看都不對勁兒,只寫了 DIB 檔頭和資訊表頭,卻沒有把
DIB 的實際內容(image)寫到檔案去。
●幸運的是...
幸運的是我再檢查 <Inside Visual C++ 5.0>(此版本無中譯本)的
光碟檔案,發現 David 已經修改過來了,新內容如下:
TRY {
pFile->Write((LPVOID)&bmfh, sizeof(BITMAPFILEHEADER));
pFile->Write((LPVOID)&m_lpBMIH, nSize);
pFile->Write((LPVOID)&m_lpImage, m_dwImageSize); // 新增此行
}
我寫了個測試程式,驗證此修改無誤。因此,<Inside Visual C++ 4.0> 或
<深入 Visual C++ 4.0> 的讀者只需依樣修改,就有一個好用的 CDib 了。
●bitmap 格式
曾經在 BBS 板上看到有網友想瞭解 Bitmap 格式。您可參考
<Inside Visual C++ 4.0> 或 <深入 Visual C++ 4.0> 第 10 章,
或 <Inside Visual C++ 5.0> 第 10 章,
以及 \msdev\include\wingdi.h,再拿此 CDib source 對照看,
很快就可完全掌握 bitmap 格式了。這裡所謂的 bitmap,
就是指 DIB(Device Independent Bitmap)。你所看到的 .bmp 檔,
其實都是 DIB。
●源由...
我怎麼會發現 David 的這個錯誤呢?
上個月為華邦電子的朋友們開了一門 C++ 課程,順帶談到 MFC 的
Serialize()。在座資深的 MFC programmer,對於 Serialize() 的
功能很感懷疑。他們懷疑:
(1) 該如何運用 Serialize() 來處理特定格式(如 Word 或 bitmap
格式)的檔案?
(2) Serialize() 的效率好嗎?從 <多型與虛擬> chap5 對 MFC Serialize
的模擬,或從 <深入淺出 MFC> chap8 對 MFC Serialize 的剖析,
都可看出,被 serialized 出去的檔案,其中有些似乎不太能掌控的 overhead
(就是那些讀檔時要用於 dynamic creation 的一些 class information),
因此無法「精準計算出檔案中某筆資料的 offset,然後一舉到位直接讀取該資料」。
這幾位朋友的經驗是,直接使用 CFile 做低階檔案動作,根本捨棄 Serialize()。
為了實驗以 Serialize() 處理 bitmap,我想到 <Inside Visual C++> 書中
現成的 class CDib,於是才發現上述的錯誤與更新。
我對華邦工程師的疑惑,回答如下:
(1) 欲以 Serialize() 處理特定格式的檔案內容,只需觀察一下上述 CDib 的
Serialize(),即可獲得靈感。應用上,假設自己的繪圖軟體需涵蓋 DIB 圖形,
那麼就在自己的 CMyDoc::Serialize() 中呼叫 CDib::Serialize() 即可。
(2) 如果閱讀了 <深入淺出 MFC> chap8 對 MFC Serialize 的剖析,其實
可以完全掌握 Serialize() 的 overhead,從而可以精確計算出某筆資料在
檔案中的精確 offset,然後一舉到位地直接讀取該筆資料。不過,這種應用
其實已經超越了 "serialize" 的字面意義。"serialize" 就是 "循序" 讀寫。
因此,如果你的應用軟體確有必要跳躍式讀取資料,你需要一個 OO database,
而不是 Serialize()。
--- the end
--
※ Origin: 楓橋驛站<bbs.cs.nthu.edu.tw> ◆ Mail: jjhou@ccca.nctu.edu.tw
> -------------------------------------------------------------------------- <
發信人: william.bbs@cis.nctu.edu.tw (何陋居主), 看板: CompBook
標 題: Re: 【Serialize 的聯想】
發信站: 交大資科_BBS (Mon Dec 14 01:47:54 1998)
轉信站: maple!news.cs.nthu!news.cis.nctu!cis_nctu
Origin: cissun13
==> 在 jjhou.bbs@bbs.cs.nthu.edu.tw (jjhou) 的文章中提到:
> (2) 如果閱讀了 <深入淺出 MFC> chap8 對 MFC Serialize 的剖析,其實
> 可以完全掌握 Serialize() 的 overhead,從而可以精確計算出某筆資料在
> 檔案中的精確 offset,然後一舉到位地直接讀取該筆資料。不過,這種應用
> 其實已經超越了 "serialize" 的字面意義。"serialize" 就是 "循序" 讀寫。
> 因此,如果你的應用軟體確有必要跳躍式讀取資料,你需要一個 OO database,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 而不是 Serialize()。
^^^^^^^^^^^^^^^^^^
如果只為了這個理由, 我想倒還不至於需要動用到 OODB.
OODB 比較適合 data/code scale 更大的場合,
或是需要做更多更複雜 query 的時候。
有點想不透, 為什麼 MFC 不使用在 OO 界早已習稱的 "persistence" 術語,
改弄出一個 "serialization" 術語?
單就字面上來說, "serialization" 一詞, 很容易跟 database、OS 界常談的
"serializable"、"serializability" 相混淆。
是因為 MFC 的 object persistence 只能做到 "serial (sequential) read/write" 嗎?
那麼, 對一個 object collection 所做的 serialization 動作,
就一定非得是 sequential 而不能 random access 或 partial update 嗎?
我想不是這樣的, 因為 MFC 的 collection classes 有個叫做
SerializeElements 的 virtual 成員函數,
也就是說:程式員可以自己做出最適合的存取方式, 即使是跳躍存取也行。
所以我實在很好奇:MFC 幹嘛捨 "persistence" 不用,
另外搞一個 "serialization" 名詞出來? :q
--
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
≡ 何陋居 ≡ 雋永難忘的事總落在願聽任其發生的人身上。
Jeffrey A. Kottler, 《旅行,重新打造自己》
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
--
* Origin: ★ 交通大學資訊科學系 BBS ★ <bbs.cis.nctu.edu.tw: 140.113.23.3>
> -------------------------------------------------------------------------- <
發信人: QueenLin.bbs@cis.nctu.edu.tw (kylin), 看板: CompBook
標 題: Re: 【Serialize 的聯想】
發信站: 交大資科_BBS (Mon Dec 14 14:23:57 1998)
轉信站: maple!news.cs.nthu!news.cis.nctu!cis_nctu
Origin: gw203.winbond.com.tw
==> 在 william@cis_nctu (何陋居主) 的文章中提到:
> ==> 在 jjhou.bbs@bbs.cs.nthu.edu.tw (jjhou) 的文章中提到:
> > (2) 如果閱讀了 <深入淺出 MFC> chap8 對 MFC Serialize 的剖析,其實
> > 可以完全掌握 Serialize() 的 overhead,從而可以精確計算出某筆資料在
> > 檔案中的精確 offset,然後一舉到位地直接讀取該筆資料。不過,這種應用
> > 其實已經超越了 "serialize" 的字面意義。"serialize" 就是 "循序" 讀寫。
> > 因此,如果你的應用軟體確有必要跳躍式讀取資料,你需要一個 OO database,
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > 而不是 Serialize()。
> ^^^^^^^^^^^^^^^^^^
> 如果只為了這個理由, 我想倒還不至於需要動用到 OODB.
> OODB 比較適合 data/code scale 更大的場合,
> 或是需要做更多更複雜 query 的時候。
> 有點想不透, 為什麼 MFC 不使用在 OO 界早已習稱的 "persistence" 術語,
> 改弄出一個 "serialization" 術語?
> 單就字面上來說, "serialization" 一詞, 很容易跟 database、OS 界常談的
> "serializable"、"serializability" 相混淆。
> 是因為 MFC 的 object persistence 只能做到 "serial (sequential) read/write" 嗎?
> 那麼, 對一個 object collection 所做的 serialization 動作,
> 就一定非得是 sequential 而不能 random access 或 partial update 嗎?
> 我想不是這樣的, 因為 MFC 的 collection classes 有個叫做
> SerializeElements 的 virtual 成員函數,
> 也就是說:程式員可以自己做出最適合的存取方式, 即使是跳躍存取也行。
> 所以我實在很好奇:MFC 幹嘛捨 "persistence" 不用,
> 另外搞一個 "serialization" 名詞出來? :q
SerializeElements是free function, 不是collection classes的成員函數,
而自5.0(含)以後的版本, SerializeElements是free function template.
儘管MFC提供persistence的機制,可以永續物件的生命週期,但確實以這個機制
所展現的功能來看, 它只是"依序"的將物件資料寫到外部儲存體中,即使可以
覆寫SerializeElements function, 但這還是循序的方式. 用"persistence"
確實可符合OO 界用語的一致性降也避免術語的混淆, 不過"serialization"
一詞也正說明MFC對persistence的支援有限及其特性.
要能隨機處理存在於外部儲存體中的物件, 那得多付出一些額外的努力, 因為
到了這兒目前MFC幫不上什麼大忙, 而這些工作又跟Database為我們所做的有
關. 至於該不該用Database system, 這需要更多的因素綜合考量. 而我們的
作法就是自行實作我們所要的random access, partial update功能.
------ by kylin
--
* Origin: ★ 交通大學資訊科學系 BBS ★ <bbs.cis.nctu.edu.tw: 140.113.23.3>
> -------------------------------------------------------------------------- <
發信人: QueenLin.bbs@cis.nctu.edu.tw (kylin), 看板: CompBook
標 題: Re: 【Serialize 的聯想】
發信站: 交大資科_BBS (Mon Dec 14 17:32:44 1998)
轉信站: maple!news.cs.nthu!newsfeed.nthu!ctu-gate!news.nctu!news.cis.nctu!cis_n
Origin: gw203.winbond.com.tw
==> 在 QueenLin@cis_nctu (kylin) 的文章中提到:
> ==> 在 william@cis_nctu (何陋居主) 的文章中提到:
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > ^^^^^^^^^^^^^^^^^^
> > 如果只為了這個理由, 我想倒還不至於需要動用到 OODB.
> > OODB 比較適合 data/code scale 更大的場合,
> > 或是需要做更多更複雜 query 的時候。
> > 有點想不透, 為什麼 MFC 不使用在 OO 界早已習稱的 "persistence" 術語,
> > 改弄出一個 "serialization" 術語?
> > 單就字面上來說, "serialization" 一詞, 很容易跟 database、OS 界常談的
> > "serializable"、"serializability" 相混淆。
> > 是因為 MFC 的 object persistence 只能做到 "serial (sequential) read/write" 嗎?
> > 那麼, 對一個 object collection 所做的 serialization 動作,
> > 就一定非得是 sequential 而不能 random access 或 partial update 嗎?
> > 我想不是這樣的, 因為 MFC 的 collection classes 有個叫做
> > SerializeElements 的 virtual 成員函數,
> > 也就是說:程式員可以自己做出最適合的存取方式, 即使是跳躍存取也行。
> > 所以我實在很好奇:MFC 幹嘛捨 "persistence" 不用,
> > 另外搞一個 "serialization" 名詞出來? :q
> SerializeElements是free function, 不是collection classes的成員函數,
> 而自5.0(含)以後的版本, SerializeElements是free function template.
Sorry!
SerializeElements是free function template, 而自VC5.0(含)以後的版本,
支援explicit specializations of function templates, SerializeElements有不同
於過去的用法.
> 儘管MFC提供persistence的機制,可以永續物件的生命週期,但確實以這個機制
> 所展現的功能來看, 它只是"依序"的將物件資料寫到外部儲存體中,即使可以
> 覆寫SerializeElements function, 但這還是循序的方式. 用"persistence"
> 確實可符合OO 界用語的一致性降也避免術語的混淆, 不過"serialization"
> 一詞也正說明MFC對persistence的支援有限及其特性.
> 要能隨機處理存在於外部儲存體中的物件, 那得多付出一些額外的努力, 因為
> 到了這兒目前MFC幫不上什麼大忙, 而這些工作又跟Database為我們所做的有
> 關. 至於該不該用Database system, 這需要更多的因素綜合考量. 而我們的
> 作法就是自行實作我們所要的random access, partial update功能.
> ------ by kylin
--
* Origin: ★ 交通大學資訊科學系 BBS ★ <bbs.cis.nctu.edu.tw: 140.113.23.3>
> -------------------------------------------------------------------------- <
※ X-Info: Mave -> ric.bbs@ptt.csie.ntu.edu.tw
※ X-Sign: 0ROABMKPH3uJ//Qs6WsU (99/07/09 7:05:56 )