天天看點

c#調用C++的DLL找不到入口點

     c#程式調用C++的dll的時候,經常出現這樣的問題:

System.EntryPointNotFoundException:Unable to find an entry point named '函數名稱' in Dll 'c++ dll檔案名'

之前也遇到過這個問題,可是怎麼解決的就忘記了,這次遇到了,就寫下這個問題的原因。

這個是我在網上查資料找到的:http://www.cnblogs.com/tallman/archive/2009/03/07/735948.html

原因就是:c++源代碼中的函數在編譯成DLL後,函數的名稱就發生了改變:會在函數的前後産生一些字元。

我們能通過eXeScope軟體來檢視c++編譯後的函數名稱是什麼,這裡要提下,eXeScope中文版本無法在x64的環境下使用,最好下英文版本。

例如:c++中的函數名是GetSvsSize,編譯後變成?GetSvsSize@@[email protected],這個時候,我們要是想調用這個函數,那麼應該這樣寫:

[DllImport(@"svsReader.dll", EntryPoint = "?GetSvsSize@@YA_NPA_WPAJ11111PAF@Z")]

       我的問題就解決了,然後我就開始想這個問題:c++在編譯之後為什麼要加上這些字元呢? 難道這是防止被Reflect?

在c#的代碼執行過程中,首先源代碼被編譯成托管子產品(分布在各自的dll中),托管子產品裡面包括IL代碼、中繼資料、還有一些标志(頭資訊),那中繼資料裡面記錄了源代碼中定義的各種類型和成員等資訊,是以c# reflect出來,裡面的類名,方法名都沒改變。

       而c++由于非托管,無法Reflect,那麼c++編譯後,是什麼樣的形式存在呢?<待續>