Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C/C++;静态与动态库示例_C++_C_Dynamic_Static - Fatal编程技术网

C++ C/C++;静态与动态库示例

C++ C/C++;静态与动态库示例,c++,c,dynamic,static,C++,C,Dynamic,Static,我正在学习静态和动态库。到目前为止,我理解了为什么我需要一个动态库。如果有什么变化,最好插入一个更新的版本,所有的应用程序都会自动更新,甚至不会被发现 a) 非常适合插件, b) 多个应用程序使用相同的库和 c) 需要更正错误时进行维护 然而,为什么会有人使用静态库呢?我是说有什么好处?某人有没有举例让我更好地理解?是为了使产品具有专利权吗 编辑:由于评论中的混乱。我了解什么是静态库,也知道动态库之间的区别。我不明白为什么有人会使用静态库而不仅仅是源代码本身。我想我现在开始明白,静态库具有以下优

我正在学习静态和动态库。到目前为止,我理解了为什么我需要一个动态库。如果有什么变化,最好插入一个更新的版本,所有的应用程序都会自动更新,甚至不会被发现

a) 非常适合插件, b) 多个应用程序使用相同的库和 c) 需要更正错误时进行维护

然而,为什么会有人使用静态库呢?我是说有什么好处?某人有没有举例让我更好地理解?是为了使产品具有专利权吗

编辑:由于评论中的混乱。我了解什么是静态库,也知道动态库之间的区别。我不明白为什么有人会使用静态库而不仅仅是源代码本身。我想我现在开始明白,静态库具有以下优点:

a) 更好的代码维护
b) 更快的编译时间

静态库很好,那么您想要的是一个小软件包,而不会出现任何与dll冲突的问题。 通过静态链接,加载和初始化库的时间也减少了很多

但作为缺点,您可以注意到二进制文件的大小有所增加


静态库基本上是对象文件的压缩包。与仅分发对象文件相比,它的唯一优势在于它是一个包含整个库的单个文件。用户可以使用您的标题和库来构建他们的应用程序

因为它只是一个对象文件的压缩包,所以编译器对对象文件所做的任何操作都可以使用静态库,例如,死代码消除和整个程序优化(也称为链接时代码生成)。与动态库不同,编译器不会在最终程序中包含未使用的共享库位


对于某些构建系统,它也使链接接缝更容易。例如,对于MSVC++,我通常会有一个“生产”EXE项目,一个“测试”EXE项目,并将常用的东西放在一个静态库中。这样,我在构建时就不必重新构建所有常见的东西。

如果您需要一些小程序,它们只使用一个非常小但有时与大型库略有不同的部分(通常发生在大型开源库中),那么最好不要构建大量的小型动态库,因为它们将变得难以管理。在这种情况下,最好只静态链接所需的部分。

编译器可以对静态库进行各种其他优化,而动态库则不能。例如,编译器可以从静态库中删除未使用的函数。它不知道在动态库中如何实现这一点。但是还有更高级的优化。编译器可以将代码从静态库函数拉入主程序,这将消除函数调用。非常聪明的编译器可以做得更多。对于静态库来说,天空确实是一个极限,但是动态库使这一点变得更加困难或不可能

然而,可能更实际的原因是,静态链接是大多数库编译器的默认设置,因此许多人最终使用它。要创建动态库,通常必须创建一个公开某些函数的附加文件。虽然文件往往相对简单,但如果您不花时间这样做,那么您的库最终都是静态的


正如在另一篇文章中提到的,使用静态库管理依赖关系往往更容易,因为您可以控制一切。您可能不知道用户系统上安装了什么dll/so。

使用动态库如果没有所有库,则应用程序不会运行。因此,如果您有一个存储库的分区,并且它变得不可用,那么应用程序也不可用。如果应用程序有静态库,那么库总是存在的,因此没有什么可以阻止应用程序工作。这通常有助于您在维护模式下启动系统


例如,在Solaris系统上,在某些分区可能不存在的情况下可能需要运行的命令存储在/sbin下。sbin是静态二进制文件的缩写。如果分区不可用,这些应用程序仍然可以工作。

静态库和动态库之间还有另一个区别,在某些情况下可能变得很重要,我很惊讶没有人提到这一点

  • 链接静态库时,符号(例如函数名)在链接(编译)期间解析,因此对库函数的调用解析为对最终可执行文件中地址的直接调用

  • 对于动态库,这发生在运行时,当库加载到进程空间时(通常在进程启动期间)。符号必须映射到进程的地址空间。根据符号的数量(可能惊人地大)和启动时加载的库的数量,延迟可能相当明显

这里有一本关于Linux上动态库的优秀深入指南-。它对我们大多数人来说太详细了,但即使是略读它也会给你带来许多令人惊讶的见解。例如,它说在OpenOffice的1.0版中,它在发布期间必须进行150多万次字符串比较

获得这种感觉的一种方法是将
LD_DEBUG
设置为符号,并将
LD_DEBUG_输出
设置为某个文件,运行一个程序并查看该文件以查看启动时进行的活动。

1。)共享库需要位置独立代码(-fpic或-fpic用于库),位置独立代码需要设置。这使得代码更大;例如:

*部分原因是如前所述的编译器效率低下

  • 使用前面的示例,t
    long realfoo(long, long);
    long foo(long x, long y){
        return realfoo(x,y);
    }
    //static
    foo:
      jmp realfoo #
    //shared (-fpic code)
    foo:
      pushl %ebx #
      call __x86.get_pc_thunk.bx #
      addl $_GLOBAL_OFFSET_TABLE_, %ebx # tmp87,
      subl $16, %esp #,
      pushl 28(%esp) # y
      pushl 28(%esp) # x
      call realfoo@PLT #
      addl $24, %esp #,
      popl %ebx #
      ret
    __x86.get_pc_thunk.bx:
      movl (%esp), %ebx #,
      ret