zoukankan      html  css  js  c++  java
  • 使用 __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更大, 执行时多了一次跳转。

  • 相关阅读:
    使用canvas技术在网页上绘制鲜花
    java连接Access数据库
    L2-009. 抢红包
    L2-008. 最长对称子串
    L1-032. Left-pad
    L1-016. 查验身份证
    L1-005. 考试座位号
    L1-030. 一帮一
    L1-023. 输出GPLT
    L1-028. 判断素数
  • 原文地址:https://www.cnblogs.com/happylong/p/4501538.html
Copyright © 2011-2022 走看看