动态链接库有没有动态链接到CRT和静态链接到CRT的两种

时间:2021-08-16 19:30:15
动态链接库有没有动态链接到CRT和静态链接到CRT的两种情况?
CRT的动态链接库版本是怎么连接到CRT的呢?

12 个解决方案

#1


几天前的帖子http://topic.csdn.net/u/20090101/17/71a086b0-66c8-4f55-b7f8-8ad72503df1a.html

#2


动态连接库与静态连接库 [转一个]
首先纠正所谓“静态连接就是把需要的库函数放进你的exe之中”的说法。在真实世界中,有三个概念:Use   static   libary,   static   linked   DLL,   dynamic   linked   DLL.   
  多数人混淆了static   libary   和   static   linked   DLL的概念,当然他们有似是而非的“相似之处”,比如都用到.lib,下面具体说明。   
          使用静态库(Use   static   libary)是把.lib和其他.obj一起build在目标文件中,目标文件可以是.exe,也可以是.dll或.oxc等。一般情况下,可以根本就没有“对应的”.dll   文件,如C   Run   Time(CRT)库。一个例子就是,写一个main(){},build出来并不是只有几个字节,当然有人会说那还有exe文件头呢?是,即使加上文件头的尺寸,build出的执行文件仍然“莫名的大”。实际上那多出来的部分就是CRT静态库。姑且可以把静态库.lib理解成外部程序的obj文件比较合理,它包含了函数的实现。   
          下面再谈static   linked   DLL   和   dynamic   linked   DLL又如何?   
          静态链接   (static   linked   DLL)从操作上在VC的Project|Settings...|Link   (tab)|General   (category)|Object/library   modules   中设置和添加。比如要使用SDK中的PropertySheet()   API,   就要在这里添加   comctl32.lib,然后再调用的源程序中#include   <prsht.h>,   使用的地方直接调用PropertySheet()。当程序.exe启动时,系统会把对应comctl32.dll加载进来。作为DLL的静态引入库的.lib不包含函数的实现,只包含用于系统加载的信息,如对应的DLL名称,函数歧视地只在对应的DLL中的便宜等等。相比动态链接而言,静态链接是很简单的。   
          动态链接是使用LoadLibrary()/GetProcessAddress()和FreeLibrary(),详见下面的例子。   
    
          {   
                  typedef   BOOL     (WINAPI   *LPFNSHELLEXECUTEEX)(LPSHELLEXECUTEINFO);   
    
                  hShell32Dll   =   LoadLibrary(TEXT("SHELL32.DLL"));   
                  if   (!hShell32Dll)   {   goto   End;   }   
    
                  lpfnShellExecuteEx   =   (LPFNSHELLEXECUTEEX)GetProcAddress(hShell32Dll,   
                          API_NAME(ShellExecuteEx));   
                  if   (!lpfnShellExecuteEx)   {   goto   End;   }   
    
                  ...   
                  fOk   =   (*lpfnShellExecuteEx)(pShellExecuteInfo);   
                  ...   
          End:   
                  if   (hShell32Dll)   {   
                          FreeLibrary(hShell32Dll);   
                  }   
                  lpfnShellExecuteEx   =   NULL;   
                  ...   
          }   
  有人会想,动态链接这样麻烦,为什么还要用呢?这里有一个技术问题,对这个问题的解决直接导致了动态加载的需求。问题是有些DLL只在某个Windows版本中存在,或某个API只在某些Windows版本中被加入指定的DLL。当你使用静态链接的.exe试图在不支持的Windows版本上运行时,系统会弹出系统对话框提示某某.dll无法加载或无法定位某某API的消息,然后就中止.exe的运行。像这样因为个别功能的实现依赖于某个DLL,当这个DLL不可用时导致整个.exe无法运行是不明智的。避免这样的结局只有用动态链接。   


=============
不能运行是原因是没有MFC的动态链接库,只要把你的程序在需要的几个动态链接库一并拷到目标机器上就行了。   
    
  或者用静态链接到MFC   
  project   properties->configuration   properties->general,在user   of   mfc中选择use   mfc   in   a   static   library

#3


学习了。

#4


顶一楼

#5


static  linked  DLL  和  dynamic  linked  DLL

这种山寨说法流传还挺广,不知从哪发源的

#6


动态链接库有没有动态链接到CRT和静态链接到CRT的两种情况? 
当然有,比如你用vc建立一个MFC规则dll,则可以选择use MFC in a shared dll/use MFC in a static library,分别对应你所说的两种情况

CRT的动态链接库版本是怎么连接到CRT的呢?
这个。。不太懂lz什么意思。dll是可以连接到别的dll或者lib的,怎么连接的,写代码呗。可以参照上面所说的MFC规则DLL的编写

lz可以下载《VC++动态链接库编程深入浅出》看看,会有帮助

#7


不懂

学习

顶楼主

#8


其实我的意思是CRT的动态链接库版本不是有MSVCRT(×).DLL这样的库吗?那么既然是.DLL的形式,那么它是不是还要链接CRT呢
,就是这个有点搞。
要是它也是链接动态的CRT版本。那么不是自己链接自己了吗,子子孙孙无穷尽也。

#9



...还是不懂lz的意思,crt不就是dll和lib两种嘛?windows程序用到crt的,要么lib连接到crt,要么dll。

“那么既然是.DLL的形式,那么它是不是还要链接CRT呢 ”
这个啥意思?dll是给别人链接的,dll为啥要连接自己。。。

#10



是不是说当别的应用程序装载CRT DLL库时,也就是MSVCRT*.DLL时因为这个库本身就含有了_DllMainCRTStartup代码,所以就直接调用这个函数了是吧。也就是说CRT DLL本身是不用再链接其他什么库了是吧
如果是这样的话那就有点概念了

#11


动态连接库与静态连接库 [转一个] 
首先纠正所谓“静态连接就是把需要的库函数放进你的exe之中”的说法。在真实世界中,有三个概念:Use  static  libary,  static  linked  DLL,  dynamic  linked  DLL.  
  多数人混淆了static  libary  和  static  linked  DLL的概念,当然他们有似是而非的“相似之处”,比如都用到.lib,下面具体说明。  
          使用静态库(Use  static  libary)是把.lib和其他.obj一起build在目标文件中,目标文件可以是.exe,也可以是.dll或.oxc等。一般情况下,可以根本就没有“对应的”.dll  文件,如C  Run  Time(CRT)库。一个例子就是,写一个main(){},build出来并不是只有几个字节,当然有人会说那还有exe文件头呢?是,即使加上文件头的尺寸,build出的执行文件仍然“莫名的大”。实际上那多出来的部分就是CRT静态库。姑且可以把静态库.lib理解成外部程序的obj文件比较合理,它包含了函数的实现。  
          下面再谈static  linked  DLL  和  dynamic  linked  DLL又如何?  
          静态链接  (static  linked  DLL)从操作上在VC的Project|Settings...|Link  (tab)|General  (category)|Object/library  modules  中设置和添加。比如要使用SDK中的PropertySheet()  API,  就要在这里添加  comctl32.lib,然后再调用的源程序中#include  <prsht.h>,  使用的地方直接调用PropertySheet()。当程序.exe启动时,系统会把对应comctl32.dll加载进来。作为DLL的静态引入库的.lib不包含函数的实现,只包含用于系统加载的信息,如对应的DLL名称,函数歧视地只在对应的DLL中的便宜等等。相比动态链接而言,静态链接是很简单的。  
          动态链接是使用LoadLibrary()/GetProcessAddress()和FreeLibrary(),详见下面的例子。  
    
          {  
                  typedef  BOOL    (WINAPI  *LPFNSHELLEXECUTEEX)(LPSHELLEXECUTEINFO);  
    
                  hShell32Dll  =  LoadLibrary(TEXT("SHELL32.DLL"));  
                  if  (!hShell32Dll)  {  goto  End;  }  
    
                  lpfnShellExecuteEx  =  (LPFNSHELLEXECUTEEX)GetProcAddress(hShell32Dll,  
                          API_NAME(ShellExecuteEx));  
                  if  (!lpfnShellExecuteEx)  {  goto  End;  }  
    
                  ...  
                  fOk  =  (*lpfnShellExecuteEx)(pShellExecuteInfo);  
                  ...  
          End:  
                  if  (hShell32Dll)  {  
                          FreeLibrary(hShell32Dll);  
                  }  
                  lpfnShellExecuteEx  =  NULL;  
                  ...  
          }  
  有人会想,动态链接这样麻烦,为什么还要用呢?这里有一个技术问题,对这个问题的解决直接导致了动态加载的需求。问题是有些DLL只在某个Windows版本中存在,或某个API只在某些Windows版本中被加入指定的DLL。当你使用静态链接的.exe试图在不支持的Windows版本上运行时,系统会弹出系统对话框提示某某.dll无法加载或无法定位某某API的消息,然后就中止.exe的运行。像这样因为个别功能的实现依赖于某个DLL,当这个DLL不可用时导致整个.exe无法运行是不明智的。避免这样的结局只有用动态链接。  


============= 
不能运行是原因是没有MFC的动态链接库,只要把你的程序在需要的几个动态链接库一并拷到目标机器上就行了。  
    
  或者用静态链接到MFC  
  project  properties->configuration  properties->general,在user  of  mfc中选择use  mfc  in  a  static  library 

#12


可能是我没问清楚吧
再换句话问下:
MSVCRT.DLL这些库它们的入口函数是什么?我找遍了CRT库的源代码,只在DLLCRT0.c文件和CRTDLL.C这两个文件中有动态
链接库的入口函数,它们分别是静态链接和动态链接的版本,静态版本中有_heap_init,但动态版本中没有_Heap_init.。

所以我认为,如果我的exe使用的是CRT的DLL版本,那么我的exe的入口函数按照CRT源代码的说明应该是crtexe.c文件中的
MainCRTStartup了,然而这个MainCRTStartup函数并没有进行heap_init,所以我猜想是在MSVCRT.DLL的入口函数是调用
DLLCRT0.c中的DLL入口函数的。

不知道是不是这样的,很疑惑。

#1


几天前的帖子http://topic.csdn.net/u/20090101/17/71a086b0-66c8-4f55-b7f8-8ad72503df1a.html

#2


动态连接库与静态连接库 [转一个]
首先纠正所谓“静态连接就是把需要的库函数放进你的exe之中”的说法。在真实世界中,有三个概念:Use   static   libary,   static   linked   DLL,   dynamic   linked   DLL.   
  多数人混淆了static   libary   和   static   linked   DLL的概念,当然他们有似是而非的“相似之处”,比如都用到.lib,下面具体说明。   
          使用静态库(Use   static   libary)是把.lib和其他.obj一起build在目标文件中,目标文件可以是.exe,也可以是.dll或.oxc等。一般情况下,可以根本就没有“对应的”.dll   文件,如C   Run   Time(CRT)库。一个例子就是,写一个main(){},build出来并不是只有几个字节,当然有人会说那还有exe文件头呢?是,即使加上文件头的尺寸,build出的执行文件仍然“莫名的大”。实际上那多出来的部分就是CRT静态库。姑且可以把静态库.lib理解成外部程序的obj文件比较合理,它包含了函数的实现。   
          下面再谈static   linked   DLL   和   dynamic   linked   DLL又如何?   
          静态链接   (static   linked   DLL)从操作上在VC的Project|Settings...|Link   (tab)|General   (category)|Object/library   modules   中设置和添加。比如要使用SDK中的PropertySheet()   API,   就要在这里添加   comctl32.lib,然后再调用的源程序中#include   <prsht.h>,   使用的地方直接调用PropertySheet()。当程序.exe启动时,系统会把对应comctl32.dll加载进来。作为DLL的静态引入库的.lib不包含函数的实现,只包含用于系统加载的信息,如对应的DLL名称,函数歧视地只在对应的DLL中的便宜等等。相比动态链接而言,静态链接是很简单的。   
          动态链接是使用LoadLibrary()/GetProcessAddress()和FreeLibrary(),详见下面的例子。   
    
          {   
                  typedef   BOOL     (WINAPI   *LPFNSHELLEXECUTEEX)(LPSHELLEXECUTEINFO);   
    
                  hShell32Dll   =   LoadLibrary(TEXT("SHELL32.DLL"));   
                  if   (!hShell32Dll)   {   goto   End;   }   
    
                  lpfnShellExecuteEx   =   (LPFNSHELLEXECUTEEX)GetProcAddress(hShell32Dll,   
                          API_NAME(ShellExecuteEx));   
                  if   (!lpfnShellExecuteEx)   {   goto   End;   }   
    
                  ...   
                  fOk   =   (*lpfnShellExecuteEx)(pShellExecuteInfo);   
                  ...   
          End:   
                  if   (hShell32Dll)   {   
                          FreeLibrary(hShell32Dll);   
                  }   
                  lpfnShellExecuteEx   =   NULL;   
                  ...   
          }   
  有人会想,动态链接这样麻烦,为什么还要用呢?这里有一个技术问题,对这个问题的解决直接导致了动态加载的需求。问题是有些DLL只在某个Windows版本中存在,或某个API只在某些Windows版本中被加入指定的DLL。当你使用静态链接的.exe试图在不支持的Windows版本上运行时,系统会弹出系统对话框提示某某.dll无法加载或无法定位某某API的消息,然后就中止.exe的运行。像这样因为个别功能的实现依赖于某个DLL,当这个DLL不可用时导致整个.exe无法运行是不明智的。避免这样的结局只有用动态链接。   


=============
不能运行是原因是没有MFC的动态链接库,只要把你的程序在需要的几个动态链接库一并拷到目标机器上就行了。   
    
  或者用静态链接到MFC   
  project   properties->configuration   properties->general,在user   of   mfc中选择use   mfc   in   a   static   library

#3


学习了。

#4


顶一楼

#5


static  linked  DLL  和  dynamic  linked  DLL

这种山寨说法流传还挺广,不知从哪发源的

#6


动态链接库有没有动态链接到CRT和静态链接到CRT的两种情况? 
当然有,比如你用vc建立一个MFC规则dll,则可以选择use MFC in a shared dll/use MFC in a static library,分别对应你所说的两种情况

CRT的动态链接库版本是怎么连接到CRT的呢?
这个。。不太懂lz什么意思。dll是可以连接到别的dll或者lib的,怎么连接的,写代码呗。可以参照上面所说的MFC规则DLL的编写

lz可以下载《VC++动态链接库编程深入浅出》看看,会有帮助

#7


不懂

学习

顶楼主

#8


其实我的意思是CRT的动态链接库版本不是有MSVCRT(×).DLL这样的库吗?那么既然是.DLL的形式,那么它是不是还要链接CRT呢
,就是这个有点搞。
要是它也是链接动态的CRT版本。那么不是自己链接自己了吗,子子孙孙无穷尽也。

#9



...还是不懂lz的意思,crt不就是dll和lib两种嘛?windows程序用到crt的,要么lib连接到crt,要么dll。

“那么既然是.DLL的形式,那么它是不是还要链接CRT呢 ”
这个啥意思?dll是给别人链接的,dll为啥要连接自己。。。

#10



是不是说当别的应用程序装载CRT DLL库时,也就是MSVCRT*.DLL时因为这个库本身就含有了_DllMainCRTStartup代码,所以就直接调用这个函数了是吧。也就是说CRT DLL本身是不用再链接其他什么库了是吧
如果是这样的话那就有点概念了

#11


动态连接库与静态连接库 [转一个] 
首先纠正所谓“静态连接就是把需要的库函数放进你的exe之中”的说法。在真实世界中,有三个概念:Use  static  libary,  static  linked  DLL,  dynamic  linked  DLL.  
  多数人混淆了static  libary  和  static  linked  DLL的概念,当然他们有似是而非的“相似之处”,比如都用到.lib,下面具体说明。  
          使用静态库(Use  static  libary)是把.lib和其他.obj一起build在目标文件中,目标文件可以是.exe,也可以是.dll或.oxc等。一般情况下,可以根本就没有“对应的”.dll  文件,如C  Run  Time(CRT)库。一个例子就是,写一个main(){},build出来并不是只有几个字节,当然有人会说那还有exe文件头呢?是,即使加上文件头的尺寸,build出的执行文件仍然“莫名的大”。实际上那多出来的部分就是CRT静态库。姑且可以把静态库.lib理解成外部程序的obj文件比较合理,它包含了函数的实现。  
          下面再谈static  linked  DLL  和  dynamic  linked  DLL又如何?  
          静态链接  (static  linked  DLL)从操作上在VC的Project|Settings...|Link  (tab)|General  (category)|Object/library  modules  中设置和添加。比如要使用SDK中的PropertySheet()  API,  就要在这里添加  comctl32.lib,然后再调用的源程序中#include  <prsht.h>,  使用的地方直接调用PropertySheet()。当程序.exe启动时,系统会把对应comctl32.dll加载进来。作为DLL的静态引入库的.lib不包含函数的实现,只包含用于系统加载的信息,如对应的DLL名称,函数歧视地只在对应的DLL中的便宜等等。相比动态链接而言,静态链接是很简单的。  
          动态链接是使用LoadLibrary()/GetProcessAddress()和FreeLibrary(),详见下面的例子。  
    
          {  
                  typedef  BOOL    (WINAPI  *LPFNSHELLEXECUTEEX)(LPSHELLEXECUTEINFO);  
    
                  hShell32Dll  =  LoadLibrary(TEXT("SHELL32.DLL"));  
                  if  (!hShell32Dll)  {  goto  End;  }  
    
                  lpfnShellExecuteEx  =  (LPFNSHELLEXECUTEEX)GetProcAddress(hShell32Dll,  
                          API_NAME(ShellExecuteEx));  
                  if  (!lpfnShellExecuteEx)  {  goto  End;  }  
    
                  ...  
                  fOk  =  (*lpfnShellExecuteEx)(pShellExecuteInfo);  
                  ...  
          End:  
                  if  (hShell32Dll)  {  
                          FreeLibrary(hShell32Dll);  
                  }  
                  lpfnShellExecuteEx  =  NULL;  
                  ...  
          }  
  有人会想,动态链接这样麻烦,为什么还要用呢?这里有一个技术问题,对这个问题的解决直接导致了动态加载的需求。问题是有些DLL只在某个Windows版本中存在,或某个API只在某些Windows版本中被加入指定的DLL。当你使用静态链接的.exe试图在不支持的Windows版本上运行时,系统会弹出系统对话框提示某某.dll无法加载或无法定位某某API的消息,然后就中止.exe的运行。像这样因为个别功能的实现依赖于某个DLL,当这个DLL不可用时导致整个.exe无法运行是不明智的。避免这样的结局只有用动态链接。  


============= 
不能运行是原因是没有MFC的动态链接库,只要把你的程序在需要的几个动态链接库一并拷到目标机器上就行了。  
    
  或者用静态链接到MFC  
  project  properties->configuration  properties->general,在user  of  mfc中选择use  mfc  in  a  static  library 

#12


可能是我没问清楚吧
再换句话问下:
MSVCRT.DLL这些库它们的入口函数是什么?我找遍了CRT库的源代码,只在DLLCRT0.c文件和CRTDLL.C这两个文件中有动态
链接库的入口函数,它们分别是静态链接和动态链接的版本,静态版本中有_heap_init,但动态版本中没有_Heap_init.。

所以我认为,如果我的exe使用的是CRT的DLL版本,那么我的exe的入口函数按照CRT源代码的说明应该是crtexe.c文件中的
MainCRTStartup了,然而这个MainCRTStartup函数并没有进行heap_init,所以我猜想是在MSVCRT.DLL的入口函数是调用
DLLCRT0.c中的DLL入口函数的。

不知道是不是这样的,很疑惑。