程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> __declspec(dllimport)的小秘密(轉),declspecdllimport

__declspec(dllimport)的小秘密(轉),declspecdllimport

編輯:C++入門知識

__declspec(dllimport)的小秘密(轉),declspecdllimport


昨天和同事使用一個dll(lib+dll)的時候,發現他在引用頭文件是,並沒有使用__declspec(dllimport),但是程序完全運行正常,不明覺厲下,去網上翻了下資料,原來是鏈接器的原因,這裡貼一個轉帖,已經寫得很清楚了。

 

鄧立波 深圳,2008-6

作者聯系方式:

email:    [email protected]

msn:     [email protected]

 

 

        按照MSDN說明,當鏈接dll的導出函數時,只需要包含頭文件和lib,__declspec(dllimport)修飾符不是必須的,但加上該修飾能使導出函數的調用效率更高。那麼,究竟原因是什麼?

假設dll導出了一個函數:
extern "C" __declspec(dllexport) void fun();
如果程序中聲明不加__declspec(dllimport),查看調用fun()函數的匯編代碼:
    004010AD   call        fun (004010d8)
其中fun被定義為一個標號(label),如下:
fun:
    004010D8   jmp         dword ptr [__imp__fun (0040e0e8)]
上面的符號__imp__fun指向的地址為fun()函數在exe中的導入節。

當聲明加上__declspec(dllimport)後,查看調用fun()函數的匯編代碼:
    004010AB   call        dword ptr [__imp__fun (0040e0e8)]

 

從上面可以看出,加上__declspec(dllimport),編譯器鏈接dll將省略一條jmp語句。
這是因為:

1。如果導出函數的聲明沒有用__declspec(dllimport) 修飾的話,編譯器並不知道這個函數是由DLL導出的,所以編譯器就把這個函數當作普通的外部引用來對待,產生一個外部引用的符號等著鏈接器解析。當鏈接器工作的時候,它是不能修改編譯器生成的結果,所以會將該符號解析為對相應函數調入節的間接調用。

2。如果導出函數的聲明用__declspec(dllimport) 修飾的話,編譯器一開始就知道這個函數是DLL導出函數,直接編譯成對調入節的調用。

 

原文:http://libo.deng.blog.163.com/blog/static/40157422200851124138373/


declspec(dllimport)聲明的詳細解釋?

declspec(dllexport)是用於避免需要自己寫DEF文件的。如果你在其他模塊中包_declspec(dllexport)的頭文件,這些項目的導出表中也會生成一個同名導出函數。
 

declspec(dllexport)與declspec(dllimport)下面語句是干嘛的

這僅僅是個宏,沒什麼特殊含義,意思是說:
如果沒有定義 __ 就定義 ___declspec(dllexport) 否則將 __ 定義為 _declspec(dllimport)
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved