|簡體中文

比思論壇

 找回密碼
 按這成為會員
搜索



查看: 434|回復: 0
打印 上一主題 下一主題

__declspec(dllimport)的小秘密(转)

[複製鏈接]

56

主題

0

好友

492

積分

中學生

Rank: 3Rank: 3

  • TA的每日心情
    擦汗
    2024-11-8 20:59
  • 簽到天數: 205 天

    [LV.7]常住居民III

    推廣值
    0
    貢獻值
    0
    金錢
    156
    威望
    492
    主題
    56
    樓主
    發表於 2014-7-18 20:46:27

    昨天和同事使用一个dll(lib+dll)的时候,发现他在引用头文件是,并没有使用__declspec(dllimport),但是程序完全运行正常,不明觉厉下,去网上翻了下资料,原来是链接器的原因,这里贴一个转帖,已经写得很清楚了。


    邓立波 深圳,2008-6

    作者联系方式:

    email:    libodeng@gmail.com

    msn:     libodeng@gmail.com



            按照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导出函数,直接编译成对调入节的调用。


    重要聲明:本論壇是以即時上載留言的方式運作,比思論壇對所有留言的真實性、完整性及立場等,不負任何法律責任。而一切留言之言論只代表留言者個人意見,並非本網站之立場,讀者及用戶不應信賴內容,並應自行判斷內容之真實性。於有關情形下,讀者及用戶應尋求專業意見(如涉及醫療、法律或投資等問題)。 由於本論壇受到「即時上載留言」運作方式所規限,故不能完全監察所有留言,若讀者及用戶發現有留言出現問題,請聯絡我們比思論壇有權刪除任何留言及拒絕任何人士上載留言 (刪除前或不會作事先警告及通知 ),同時亦有不刪除留言的權利,如有任何爭議,管理員擁有最終的詮釋權。用戶切勿撰寫粗言穢語、誹謗、渲染色情暴力或人身攻擊的言論,敬請自律。本網站保留一切法律權利。

    手機版| 廣告聯繫

    GMT+8, 2024-11-20 15:57 , Processed in 1.044198 second(s), 26 queries , Gzip On.

    Powered by Discuz! X2.5

    © 2001-2012 Comsenz Inc.

    回頂部