2012-02-29 24 views
0

the example of hooking C++ methods with MobileSubstrate我發現這一點:爲什麼在掛鉤C++函數時MobileSubstrate使用這樣一個長函數名?

void (*X_ZN20WebFrameLoaderClient23dispatchWillSendRequestEPN7WebCore14DocumentLoaderEmRNS0_15ResourceRequestERKNS0_16ResourceResponseE) (void* something, void* loader, unsigned long identifier, void* request, const void** response); 

爲什麼我們需要這個x_zn20 ... 23 .... ... 7名之間14等?這是什麼意思?我不認爲這是真名。

+0

只是一個猜測,但我認爲這與名稱混搭有關。在C++中聲明的函數名稱會被「搗亂」成爲令人討厭的符號名稱,因爲編譯器會處理像重載函數和多個函數名稱相同的類。 – 2012-02-29 18:09:52

+1

這與C或Objective-C有什麼關係? – 2012-02-29 18:38:34

+2

這裏顯示的代碼是C,@Nicol。它是鉤住C++函數的C代碼。 MobileSubstrate在C和Objective-C中提供了示例。 – 2012-02-29 18:59:52

回答

3

C++發送到二進制文件的符號名稱,以區分void foo(int)void foo(double)。另外,在許多平臺上,它需要編碼X::Y以使其成爲字母數字字符串。這增加了額外的字符並且依賴於平臺。

+0

編譯器特定。許多在同一平臺上的編譯器可能有不同的名稱修改方案。因此,來自不同編譯器的對象很少一起工作。 – 2012-02-29 18:37:01

+0

@LokiAstari:反過來說:對象不能一起工作,除非它們遵循一個通用的ABI,並且名稱阻止可以在99.9%的時間內阻止不兼容的對象文件的鏈接。 – MSalters 2012-03-01 09:16:05

0

它看起來像一些平臺特定的hack綁定到編譯對象中的符號。

您應該查找包含該函數名稱的頭文件並正確調用它。

這很糟糕,因爲隨着編譯器的發展以及代碼庫更改符號名稱的細節將發生變化。

+0

當你掛鉤一個私有函數時,你很少有權訪問聲明該函數的頭文件。而且,由於您正在掛鉤已編譯的代碼,因此最好使用它在編譯模塊中顯示的名稱。否則,您需要重新實現其他模塊的編譯器所使用的相同的名稱修改例程。 – 2012-02-29 19:05:55

3

您看到的符號被稱爲name mangling

這是一種編碼方法簽名(在二進制文件中)的方法,以便它們在整個二進制文件中是唯一的,即使兩個方法具有相同的名稱並且它們屬於相同名稱的類但僅與範圍不同命名空間)或參數