C++
背景
在C&C++中
一、inline關鍵字用來定義一個類的內聯函式,引入它的主要原因是用它替代C中表達式形式的宏定義。
表達式形式的宏定義一例:
#define ExpressionName(Var1,Var2) ((Var1)+(Var2))*((Var1)-(Var2))
取代這種形式的原因如下:
1.C中使用define這種形式宏定義的原因是因為,C語言是一個效率很高的語言,這種宏定義在形式及使用上像一個函式,但它使用預處理器實現,沒有了 參數壓棧,代碼生成等一系列的操作。因此,效率很高,這是它在C中被使用的一個主要原因。
2.這種宏定義在形式上類似於一個函式,但在使用它時,僅僅只是做預處理器符號表中的簡單替換,因此它不能進行參數有效性的檢測,也就不能享受C++編譯器嚴格類型檢查的好處,另外它的返回值也不能被強制轉換為可轉換的合適的類型。這樣,它的使用就存在著一系列的隱患和局限性。
3.在C++中引入了類及類的訪問控制,這樣,如果一個操作或者說一個表達式涉及到類的保護成員或私有成員,你就不可能使用這種宏定義來實現(因為無法將this指針放在合適的位置)。
4.inline推出的目的,也正是為了取代這種表達式形式的宏定義,它消除了宏定義的缺點,同時又很好地繼承了宏定義的優點。
預定義
對應於上面的1-3點,闡述如下:
1.inline定義的類的內聯函式,函式的代碼被放入符號表中,在使用時直接進行替換(像宏一樣展開),沒有了調用的開銷,效率也很高。
2.很明顯,類的內聯函式也是一個真正的函式,編譯器在調用一個內聯函式時,會首先檢查它的參數的類型,保證調用正確。然後進行一系列的相關檢查,就像對待任何一個真正的函式一樣。這樣就消除了它的隱患和局限性。
3.inline可以作為某個類的成員函式,當然就可以在其中使用所在類的保護成員及私有成員。
在何時使用inline函式:
首先,你可以使用inline函式完全取代表達式形式的宏定義。
另外要注意,內聯函式一般只會用在函式內容非常簡單的時候。這是因為,內聯函式的代碼會在任何調用它的地方展開,如果函式太複雜,代碼膨脹帶來的惡果很可能會大於效率的提高帶來的益處。內聯函式最重要的使用地方是用於類的存取函式。
使用方法
inline的使用:
1.在類中定義這種函式:
class ClassName{
.....
....
INT GetWidth(){return m_lPicWidth;}; // 如果在類中直接定義,不需要用inline修飾,編譯器自動化為內聯函式
.... //此說法在《C++ Primer》中提及
....
}
2.在類外定義前加inline關鍵字:
此外還有一些規則需注意:
1.inline說明對編譯器來說只是一種建議,編譯器可以選擇忽略這個建議。比如,你將一個長達1000多行的函式指定為inline,編譯器就會忽略這個inline,將這個函式還原成普通函式。
2.在調用內聯函式時,要保證內聯函式的定義讓編譯器"看"到,也就是說內聯函式的定義要在頭檔案中,這與通常的函式定義不一樣。但如果你習慣將函式定義放在CPP檔案中,或者想讓頭檔案更簡潔一點,可這樣做:
以上方法是通用、有效的,可放心使用,不必擔心在頭檔案包含CPP檔案會導致編譯錯誤。
CSS
display:inline
它可以讓行內顯示為塊的元素,變為行內顯示,例如:
DIV1
DIV2
這裡DIV1和DIV2分別占一行,但是你給他們加上屬性後變了。
DIV1 DIV2
DIV1和DIV2這時候顯示在同一行了,試試看吧
和 display:inline 對應的是 display:block,block 會讓套用了該 CSS 屬性的 HTML 標記變成塊級別元素,例如 SPAN 是行內顯示的,但是你加了 display:block 屬性就不一樣了。
[font style= "display:block "] SPAN1 [/font]
[font style= "display:block "] SPAN2 [/font]
block一般一個塊占一行,除非float
inline是自動排為一行,就象段內的文字一樣,可成為多行。
display:inline比較經典的用法是用在 <ul> 下的 <li> 中
display:inline 對應不顯示為 display:none
display:block 對應不顯示為 hidden
說通俗點,樣式為none的元素不占位置,而樣式為hidden的元素雖然不顯示但還是占地方。
InLine hook
字面含義
從字面上來理解,inline hook即內置hook ,內部跳轉hook,從內部聯結到其它函式的hook。
指直接修改目標函式的指令,用一個跳轉或者其他指令來達到掛鈎(執行自寫的其他函式)的目的。
這是相對一般的 函式地址hook來說,一般的hook方法是指是在調用函式處修改函式地址,而不是在原來的函式體裡面做修改。如:CALL 0x10000001 改成 CALL 0x10000002。
還有就是 函式地址列表hook。在程式的不同層面有不同的函式地址清單 ,如套用層的IAT表,驅動層的SSDT和IDT表,此即在上述函式地址清單中修改函式地址。函式在套用層的IAT表地址如同函式的含糊地址,如X小區,驅動層的如詳細地址,如X棟X室,驅動的保護就如同小區保全起到保護作用。
比喻
如果把一個程式比作一本書,那么:
inline hook如同修改內頁內容,寫上(由此處跳轉到XXX頁),位置在開始的叫淺層inline hook,靠後的則為深層inline hook。
SSDT hook、IDT hook和 IAT hook如同修改目錄中章節的地址,把XXX節 xxx頁改為yyy頁。
比較
一般來說,改地址的hook,其使用時比較穩定。 inline hook 更加高級一點,一般也跟難以被發現。
附
inline:內置,線上的,在線上的