• 使用 __declspec(dllimport) 能够优化对DLL导出函数的调用.


      使用 __declspec(dllimport) 能够优化对DLL导出函数的调用。

    不使用时:

          [DLL]
            #ifdef THEDLL_EXPORTS
            #define THEDLL_API __declspec(dllexport)
            #else
            #define THEDLL_API __declspec(dllimport)
            #endif
            
            // THEDLL_API 
            int fntheDll(void);
            
            [EXE]
            #include "..\theDll\theDll.h"
            #pragma  comment(lib, "..\Release\theDll.lib")
    
            #include <Windows.h>
            #include <iostream>
            using namespace std;
    
            int _tmain(int argc, _TCHAR* argv[])
            {
                cout << fntheDll() << endl;
                return 0;
            }
            
            问题是: 链接器生成不必要的 thunk:
            
            cout << fntheDll() << endl;
            00BC1000 A1 3C 20 BC 00   mov         eax,dword ptr [__imp_std::endl (0BC203Ch)]
            00BC1005 50               push        eax  
            00BC1006 E8 13 08 00 00   call        fntheDll (0BC181Eh) 
                                                                ^
            // 链接器生成的 thunk                                 |
            fntheDll:                                           |
                 |----------------------------------------------/
                 v
            00BC181E FF 25 B8 20 BC 00 jmp         dword ptr [__imp_fntheDll (0BC20B8h)]
                                                                         |
                                                                         |
                                                                         --------> EXE IAT(导入表)中的地址, 即, 函数 fntheDll() 在EXE地址空间的位置.

    使用时:

         [DLL]
            #ifdef THEDLL_EXPORTS
            #define THEDLL_API __declspec(dllexport)
            #else
            #define THEDLL_API __declspec(dllimport)
            #endif
    
            THEDLL_API int fntheDll(void);
    
            [EXE]
            #include "..\theDll\theDll.h"
            #pragma  comment(lib, "..\Release\theDll.lib")
    
            #include <Windows.h>
            #include <iostream>
            using namespace std;
    
            int _tmain(int argc, _TCHAR* argv[])
            {
                cout << fntheDll() << endl;
                return 0;
            }
            
            链接器没有生成 thunk:
    
            cout << fntheDll() << endl;
            00E11000 A1 3C 20 E1 00   mov         eax,dword ptr [__imp_std::endl (0E1203Ch)]
            00E11005 50               push        eax  
            00E11006 FF 15 B8 20 E1 00 call       dword ptr [__imp_fntheDll (0E120B8h)]
                                                                       |
                                                                       |
                                                                       --------> EXE IAT(导入表)中的地址, 即, 函数 fntheDll() 在EXE地址空间的位置.

      结论: 所以通过 __declspec(dllimport) 指示导入函数, 链接器不会生成不必要的中间thunk, 而该thunk使生成的EXE更大, 执行时多了一次跳转。

  • 相关阅读:
    P2216 [HAOI2007]理想的正方形(dp+单调队列优化)
    洛谷P1415 拆分数列(dp)
    2017 ACM-ICPC EC-Final ShangHai 东亚洲大陆-上海
    sql查询50题
    虚拟机安装
    Kick Start 2019 Round A Parcels
    Kick Start 2019 Round B Energy Stones
    【DP 好题】Kick Start 2019 Round C Catch Some
    【图论好题】ABC #142 Task F Pure
    【DP 好题】hihoCoder #1520 古老数字
  • 原文地址:https://www.cnblogs.com/happylong/p/4501538.html
Copyright © 2020-2023  润新知