CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

DLL中函数的静态调用和动态调用到底有什么差别?

楼主darkread(黑色阅读)2004-05-04 16:43:14 在 VC/MFC / 基础类 提问

这个差别不是说,动态调用是要LoadLibrary,静态的不用  
   
  我是想知道在二进制代码上的区别,也就是说特别是静态调用,到底怎么解释,比如,一般情况下,我们在VC中如果要使用CreateWindow函数,只要包含一个Windows.h,然后就可以在在代码中写入CreateWindow(...),这是静态调用,  
  也可以LoadLibrary(...),然后GetProcAddress(),然后CreateWindow,  
   
  在代码上是不同的,但是如果是在二进制代码级别上是否也有差别,还是一样的。  
   
  我现在的想法是应该是一样的,如果不一样那么是否就意味着微软在win9x的时候就确定了每一个API的地址,一直保持到win2k,winXP呢?好像是有难度的?静态调用只是实现形成了Lib,我们每次不用手动LoadLibray(),但是有产生了另一个问题,我们每调用一次API,如果使用静态调用那么是不是就要LoadLibrary,GetProcAddress一次呢,因为在它形成Lib的时候,它也不知道我们调用GreateWindow的时候是不是已经LoadLibray了,所以每次都要这么做的  
   
  大家说说我这种想法到底是错是对啊,已经困扰我很久了 问题点数:20、回复次数:9Top

1 楼darkread(黑色阅读)回复于 2004-05-04 16:50:58 得分 0

这个是静态调用的反汇编  
   
  #include   "stdafx.h"  
  #include   "Windows.h"  
   
  int   main(int   argc,   char*   argv[])  
  {  
  MessageBox(NULL,"Somebody   Help!",NULL,MB_OK);  
  printf("Hello   World!\n");  
  return   0;  
  }  
   
  7:         int   main(int   argc,   char*   argv[])  
  8:         {  
  00401010       push                 ebp  
  00401011       mov                   ebp,esp  
  00401013       sub                   esp,40h  
  00401016       push                 ebx  
  00401017       push                 esi  
  00401018       push                 edi  
  00401019       lea                   edi,[ebp-40h]  
  0040101C       mov                   ecx,10h  
  00401021       mov                   eax,0CCCCCCCCh  
  00401026       rep   stos         dword   ptr   [edi]  
  9:                 MessageBox(NULL,"Somebody   Help!",NULL,MB_OK);  
  00401028       mov                   esi,esp  
  0040102A       push                 0  
  0040102C       push                 0  
  0040102E       push                 offset   string   "Somebody   Help!"   (0042002c)  
  00401033       push                 0  
  00401035       call                 dword   ptr   [__imp__MessageBoxA@16   (0042528c)]  
  0040103B       cmp                   esi,esp  
  0040103D       call                 __chkesp   (00401100)  
  10:               printf("Hello   World!\n");  
  00401042       push                 offset   string   "Hello   World!\n"   (0042001c)  
  00401047       call                 printf   (00401080)  
  0040104C       add                   esp,4  
  11:               return   0;  
  Top

2 楼mynameisno1(no.1)回复于 2004-05-04 16:56:02 得分 0

静态调用的话,编译时要包含lib文件和头文件,动态调用就不用这两个东东  
   
  我想主要的一点区别就是,静态调用的库在程序启动时就装载,动态调用则是要用的时候手工装载,用完了还可以卸载(什么函数来的,忘了)  
   
  从函数执行效率等方面来看应该没什么区别  
  Top

3 楼darkread(黑色阅读)回复于 2004-05-04 17:07:34 得分 0

这个是在我同学的机器上编译的XP+VC7  
   
  ---   f:\vc70\test_del\test_del\main.cpp   -----------------------------------------  
  #include   "stdio.h"  
  #include   "windows.h"  
  int   main()  
  {  
  00411A40     push                 ebp      
  00411A41     mov                   ebp,esp    
  00411A43     sub                   esp,0C0h    
  00411A49     push                 ebx      
  00411A4A     push                 esi      
  00411A4B     push                 edi      
  00411A4C     lea                   edi,[ebp-0C0h]    
  00411A52     mov                   ecx,30h    
  00411A57     mov                   eax,0CCCCCCCCh    
  00411A5C     rep   stos         dword   ptr   [edi]    
  MessageBox(NULL,"123",NULL,MB_OK);  
  00411A5E     mov                   esi,esp    
  00411A60     push                 0          
  00411A62     push                 0          
  00411A64     push                 offset   string   "123"   (424024h)    
  00411A69     push                 0          
  00411A6B     call                 dword   ptr   [__imp__MessageBoxA@16   (42A314h)]    
  00411A71     cmp                   esi,esp    
  00411A73     call                 @ILT+935(__RTC_CheckEsp)   (4113ACh)    
  printf("OKKKKK");  
  00411A78     push                 offset   string   "OKKKKK"   (42401Ch)    
  00411A7D     call                 @ILT+1170(_printf)   (411497h)    
  00411A82     add                   esp,4    
  return   0;  
  00411A85     xor                   eax,eax    
  }Top

4 楼darkread(黑色阅读)回复于 2004-05-04 17:13:36 得分 0

这个又是另外一个同学的  
  XP+VC6  
   
   
   
  ---   G:\test_del\test_del.cpp     ---------------------------------------------------------------------------------------------  
  1:         //   test_del.cpp   :   Defines   the   entry   point   for   the   console   application.  
  2:         //  
  3:  
  4:         #include   "stdafx.h"  
  5:         #include   "windows.h"  
  6:         int   main(int   argc,   char*   argv[])  
  7:         {  
  00401010       push                 ebp  
  00401011       mov                   ebp,esp  
  00401013       sub                   esp,40h  
  00401016       push                 ebx  
  00401017       push                 esi  
  00401018       push                 edi  
  00401019       lea                   edi,[ebp-40h]  
  0040101C       mov                   ecx,10h  
  00401021       mov                   eax,0CCCCCCCCh  
  00401026       rep   stos         dword   ptr   [edi]  
  8:                 MessageBox(NULL,"123",NULL,MB_OK);  
  00401028       mov                   esi,esp  
  0040102A       push                 0  
  0040102C       push                 0  
  0040102E       push                 offset   string   "123"   (0042002c)  
  00401033       push                 0  
  00401035       call                 dword   ptr   [__imp__MessageBoxA@16   (0042528c)]  
  0040103B       cmp                   esi,esp  
  0040103D       call                 __chkesp   (00401100)  
  9:                 printf("Hello   World!\n");  
  00401042       push                 offset   string   "Hello   World!\n"   (0042001c)  
  00401047       call                 printf   (00401080)  
  0040104C       add                   esp,4  
  10:               return   0;  
  0040104F       xor                   eax,eax  
  11:       }  
  00401051       pop                   edi  
  00401052       pop                   esi  
  00401053       pop                   ebx  
  00401054       add                   esp,40h  
  00401057       cmp                   ebp,esp  
  00401059       call                 __chkesp   (00401100)  
  0040105E       mov                   esp,ebp  
  00401060       pop                   ebp  
  00401061       ret  
  Top

5 楼darkread(黑色阅读)回复于 2004-05-04 17:17:45 得分 0

这个是XP+VC7的  
  00411A6B     call                 dword   ptr   [__imp__MessageBoxA@16   (42A314h)]  
  这个是XP   +   VC6的  
  00401035       call                 dword   ptr   [__imp__MessageBoxA@16   (0042528c)]  
  很奇怪吧?我晕了,42A314h和0042528c应该是MessageBoxA◎16的地址吧,怎么就不一样呢?Top

6 楼ahu9870(阿胡9870)回复于 2004-05-04 18:28:29 得分 10

正如你已经提到的,动态装载DLL与静态装载的主要区别是:  
   
          对于静态链接的DLL,主程序所引用的DLL的所有导出函数都会在LINK时建立一张引入表(见PE文件格式);在装载主程序时,同时会装入DLL,并由操作系统对其进行重定位。如果这时DLL在搜索路径中不存在,主程序将出现装载错误而失败,根本不能运行;而且,在整个主程序的运行期中,DLL不能卸载;  
   
          而对于动态链接的DLL,则是由显式的   LoadLibrary->GetProcAddress来进行调用的。主程序在装载时,并不会同时装入DLL,如果这时DLL在搜索路径中不存在,主程序不会出现装载错误。只有当LoadLibrary执行时,才真正开始主程序与DLL的引用和依赖关系。而且,当该DLL的导出函数不再需要时,可以随时卸载DLL。Top

7 楼jiang89f(new think)回复于 2004-05-04 19:28:19 得分 0

恩,我觉得初学用静态的好点,过一段用动态好Top

8 楼darkread(黑色阅读)回复于 2004-05-04 19:33:37 得分 0

我问的是动态和静态实现,在二进制代码上是否有差别??  
  请看清楚题目!!!!  
  Top

9 楼fbmsf(FBM)回复于 2004-05-05 10:33:19 得分 10

没有区别。只是用两种不同的方式来获得   api   的地址,  
   
                这个是XP+VC7的  
  00411A6B     call                 dword   ptr   [__imp__MessageBoxA@16   (42A314h)]  
  这个是XP   +   VC6的  
  00401035       call                 dword   ptr   [__imp__MessageBoxA@16   (0042528c)]  
   
  42A314h)],,,0042528c)]这儿分别还有一条jmp   77xxxxxx的代码,这才是关键。Top

相关问题

  • 如何在VB中静态调用DLL函数
  • 动态调用DLL比静态调用有什么好处,怎样动态调用dll中的函数?
  • DLL调用函数问题
  • DLL的函数调用????
  • 函数与事件的动态调用、静态调用!
  • 如何在静态成员函数中调用非静态成员函数?
  • 关于调用静态dll
  • 关于DLL中的函数调用
  • 调用.DLL中函数的问题?
  • 如何调用DLL中的函数。

关键词

  • 函数
  • 代码
  • 二进制
  • dll
  • api
  • null
  • 调用
  • 静态
  • 主程序
  • 装载

得分解答快速导航

  • 帖主:darkread
  • ahu9870
  • fbmsf

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo