MFC DLL指南 二 演化論

2021-04-17 00:11:40 字數 2565 閱讀 1296

我們上節討論的結果是.dlls對於任何的程式設計師都是非常實用的工具.然而,使用他們卻有很多限制,任何人在作的時候都要意識到這點.

mfc issues

在上一節已經提到了這個,但是很有再一次提的價值.mfc擴充套件的.dll只能在和客戶端的程式用相同的mfc和正確的mfc的**庫的情況下才好使.正規的.dll也是如此.

compiler incompatibility issues

乙個很重要的問題就是在以c++為基礎的.dlls,當它們建立在某乙個編譯器上,而呼叫它們的客戶端卻建立在另乙個編譯器上,通常情況下,再多的努力,它也不會工作.:(

ansi協會制定了c和c++的語言的標準.也就是說,它指定了c和c++的函式和資料型別必須由乙個編譯器來支援.但是它並沒有提供乙個完整的基於二進位制級的關於如何用函式和資料型別的實現.結果,編譯器廠商就根據自己的方式來自由的實現其語言功能.

很多的c/c++程式設計師知道不同的編譯器操作的資料型別是不同的.乙個編譯器為int型變數分配2bytes,但另乙個也許會分配4bytes.乙個會用4bytes的double,另乙個可能用8bytes的.在函式實現和操作符過載方面就有更大的差別了.不同的編譯器的差別比你想的還要多,所以,這些不同使你的.dll不能執行於某些的程式上.

編譯器的不相容問題可以通過插入pragmas和其他的重編譯說明到你的**來解決,但是很難,而且不易讀.但是用到不相容的編譯器確實是不可避避免的.解決編譯器不相容問題的最好的方法是讓你的.dll匯出乙個簡單的介面類,讓它指回你的.dll,我們將在下面討論.

recompiling

讓我們假設你建立了內含名為cmyclass的類的.dll.當乙個客戶程式連到你的.dll,.dll建立這個類的例項並匯出這個例項.假設你的匯出例項為30位元組.

現在假設你對cmyclass做了一些改動,加了乙個int型變數,這樣你的匯出的cmyclass的例項就由原來的30位元組變成了34位元組,你將新的.dll給使用者,讓它替代原來的.現在,錯誤來了,客戶程式期待乙個30位元組的例項,但是你的新的.dll卻送來了34位元組的例項,客戶程式將丟擲異常.

客戶程式並不需要改變**,所有要做的就是匯入乙個cmyclass類的例項.在**的某處,加上這行:

_declspec(dllimport) cmyclass myobject;

客戶程式的**不需任何改變,只需要重編譯客戶程式來解決此問題,重編譯後,客戶程式將等待34位元組的例項.

這是很嚴重的問題,不重新編譯客戶端而只在改變.dll後將此.dll重置是我們的目標.然而,你的.dll要匯出整個類或乙個類的例項,那麼此目標是不可能實現的.你必須重編譯客戶端.如果你沒有客戶端的源**,你將使用不了新的.dll.

solutions

如果對上面的問題有乙個很好的解決,那麼我們不會用com了.這裡有一些建議:

盡可能的用mfc的擴充套件的.dlls.雖然這樣限制了你的客戶程式的型別,但是解決了編譯器不相容的問題.

如果你的.dll匯出類或者類的例項,你不得不在修改了.dll後重新編譯你的客戶端.為了避免這樣,你必須做到分解你要匯出的類,實現匯出類的乙個介面.最好的方法是,建立乙個作為第乙個類的介面的類,這樣你改變了匯出類的話,介面類不變,客戶程式無需重新編譯.

這裡有乙個例子.假設你要匯出cmyclass類.cmyclass有兩個公有函式,int functiona(int)和int functionb(int).替代匯出cmyclass,我將建立乙個匯出介面cmyinte***ce.cmyinte***ce將含有乙個指向cmyclass的例項.這裡給出它的標頭檔案:

class afx_ext_class cmyinte***ce

;這份標頭檔案將用在.dll和客戶端程式.注意,前面的宣告意味著沒有cmyclass的備份也可以編譯.

在.dll內部,這樣實現cmyinte***ce:

cmyinte***ce::cmyinte***ce( )

~cmyinte***ce::~cmyinte***ce( )

cmyinte***ce::functiona( )

cmyinte***ce::functionb( )

因此,cmyclass的每乙個函式,cmyinte***ce將提供相應的函式.客戶程式將和客戶程式沒有聯絡.如果它想呼叫cmyclass::functiona,只需呼叫cmyinte***ce::functiona.介面類會用指標呼叫cmyclass.用這種布局你可以改變cmyclass了----不用擔心cmyclass的大小變了.cmyinte***ce的介面的大小不變.即使你給cmyclass加了乙個私有變數,cmyinte***ce的大小也不會變.要是你加了公有成員,就在cmyinte***ce裡邊直接加上對應新變數的"getter" 和 "setter" 函式,不用擔心,加入新的函式,cmyinte***ce介面類的大小不會改變.

建立乙個單獨的介面可以避免編譯器不相容,客戶端重編譯的問題.只要介面類不變,就不需重編譯.但仍然有兩個小問題,一:對於每乙個cmyclass的公有的成員變數,你必須在cmyinte***ce裡建立實際的對應的函式或變數.這個例子中只有兩個函式,所以很簡單.如果cmyclass有成千上萬的函式和變數,這將變得很困難,而且易錯.二:你將增大程序的開銷.客戶程式不再直接訪問cmyclass,替代的通過訪問cmyinte***ce來訪問cmyclass.如果乙個函式要被呼叫成千次,那此程序將會耗用很長時間.

職場演化論

菜鳥之所以菜,是因為置入乙個新環境後,一時間無法正確自我認知而造成的懵懂和慌亂。解決辦法有二 一 用時間換自己的經驗 二 用別人的經驗節約自己的時間。第乙個階段瞎子摸象 十幾年的學習基本無用處 不要怕自己無知,也不用掩飾無知。第二階段發現自我,能做什麼。第三階段戰勝老鳥。人行財 三大職能部門 人力資...

大學演化論摘抄

不要貪一時之快,而應該多做長期投資,一些 的 收益 可能被忽略。另外該花錢的才花錢,日常生活能省則省。千萬不要忽略時間成本,成本,收益。增強自己的內驅力 執行力 把挑戰需要的能力當作自己的目標去準備,而不是說 我還沒有準備好 千萬不要自己感動自己,更高的效率比時間的堆疊更重要,想想你高考前一些無用的...

上帝 演化論 概率學

地球上物種的多樣性讓我們非常的感嘆造物者的神奇。演化論告訴我們,這許多的物種是幾十億年前從海洋裡面進化來的。突然又乙個很奇怪的想法,就是上帝拿很多引數在 調整,然後我們輸出了許多許多的物種。引數可能有 1 有沒有羽毛 2 能否飛行 3 有幾條腿 4 雌雄 5 能否說話 6 眼睛什麼顏色 7 的顏色 ...