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更大, 执行时多了一次跳转。

  • 相关阅读:
    Quartz:基本用法总结
    Linux: ssh免密登陆
    AOP计算方法执行时长
    架构师常用的5种图
    正态分布及正态随机变量
    【转】Ubuntu下解决Depends: xxx(< 1.2.1) but xxx is to be installed
    Robotium和Espresso大PK——速度篇
    使用docker安装mysql并连接
    直接拷贝数据文件实现Oracle数据迁移
    ORA-08103:对象不再存在
  • 原文地址:https://www.cnblogs.com/happylong/p/4501538.html
Copyright © 2011-2022 走看看