對於大多數驅動開發初學者來說,有時候我們寫的代碼,或者在網上copy的代碼,你會發現編譯程序是出現這樣的錯誤error LNK2019: unresolved external symbol
_DriverEntry@8 referenced in function
_GsDriverEntry@8
e:\vs2008~1\listpr~1\listpr~1\objchk_win7_x86\i386\ListProcess.sys : fatal error LNK1120: 1 unresolved externals
當你在懷疑自己的代碼,或者你看到的博客文章時。其實你大可不必有這樣的疑慮,居然編譯器沒有提示是代碼編寫出錯,那麼你的代碼編寫是正確,想想或許是其他原因。這裏不賣關子了,直接告訴大家我其實是編譯器騙了你。我們下來說說這事什麼錯誤——這是一個鏈接錯誤,原來是系統在鏈接時找不到入口函數_DriverEntry@8。在VS2008或者VS2010中編譯默認的編譯方式是採用C++方式。錯誤意思:顯然是C編譯器對DriverEntry進行編譯後的結果,前綴“_”是C編譯器特有的,後綴“@8”是所有參數的長度。原來我們現在使用的是C++編譯器,一定是它把DriverEntry編譯成了系統無法認識的另一副模樣了(實際上,C++編譯器會把它編譯成以“?DriverEntry@@”開頭的一串很長的符號)。到這裏我想你應該猜到怎麼解決這個問題了。
我這裏提供兩個解決方法:
方法一:
在這個函數前面加上extern "C"修飾符,上述問題即立刻消失了。extern "C"提醒編譯器要使用C編譯格式編譯DriverEntry函數,這樣編譯生成的函數名稱爲“_DriverEntry@8”,鏈接器即可正確地識別出符號了。編譯後錯誤就消失了。這裏大家要記得喲,如果下次不是函數DriverEntry 而是其他函數XXXXX也可以採用相同的方法。這叫舉一反三,學習方法很重要!
方法二:
這個方案其實很簡單,直接把.cpp文件的改成.c文件。爲什麼這樣也可以呢?簡單說說,我們的.cpp文件採用的是C++的編譯的方式,而.c文件採用的是C語言的編譯方式。所以這樣也可以解決問題。
我個人建議大家使用方法一,這樣代碼的移植性會相對增加。