将静态库和动态库链接到相同的可执行文件会导致哪些问题?

Posted

技术标签:

【中文标题】将静态库和动态库链接到相同的可执行文件会导致哪些问题?【英文标题】:What problems can linking both static and dynamic libraries into the same executable cause? 【发布时间】:2017-02-01 20:55:58 【问题描述】:

我在今天的一次求职面试中被问到这个问题。不幸的是,我不确定我在这里是否正确复制了它。我只记得,我不太了解它。问题可能是

"加载静态和动态编译的dll有什么问题 原因?”

我不知道答案,但面试官告诉我至少有两个主要问题

    运行时库:可能存在一些不兼容的内存分配和取消分配。

    很遗憾,我们在这里被打断了,我们没有回过头来回答这个问题。

请你帮我理解这个问题可能是什么,以及答案是什么?

我也不是很明白第一点。我以为一个程序中只能有一个malloc,我错了吗?

【问题讨论】:

【参考方案1】:

假设 A.dll 与标准库版本 1.0 静态链接。它有一个看起来像这样的函数:

  char * f() 
     return malloc( 100 );   // uses malloc 1.0
  

现在假设有另一个库 B.dll 与 A.dll 动态链接并与标准库版本 1.1 静态链接。它有一个看起来像这样的函数:

   void g() 
      char * p = f();  // returns the result of malloc 1.0
      free( p );   // uses free 1.1
   

然后你可能(我说“可能”,因为这些都不是标准化的)有一个指针,它是用标准库 1.0 动态分配的,但在 1.1 版中被释放了。这通常会导致严重且难以诊断的问题。

【讨论】:

谢谢! “标准库”是指运行时库,还是暗示它包含在标准库中? C 和 C++ 标准都没有说明运行时库。 malloc 和 free 是这两种语言的标准库的一部分。【参考方案2】:

因为静态编译的 dll 是在运行前编译的,如果你需要改变任何东西(比如函数),你必须重新编译 .exe。静态编译的 dll 也比动态链接的 dll 大。动态链接的 dll 在运行时链接,因此每个程序都可以访问它们,因为所有函数在内存中都有特殊的位置,而没有它们的多个副本(例如静态编译时)。希望这会有所帮助。

【讨论】:

没有静态或动态编译之类的东西。不,您不必重新编译 .exe - 您可能需要重新链接它。

以上是关于将静态库和动态库链接到相同的可执行文件会导致哪些问题?的主要内容,如果未能解决你的问题,请参考以下文章

什么叫静态库和动态库

C语言里面的动态库和静态库

Linux下动态库和静态库制作与调用

gcc 编译使用动态链接库和静态链接库

gcc编译工具生成动态库和静态库之一----介绍

如何使用cmake生成基于静态库的动态链接库