草庐IT

c++ - 共享对象 (.so)、静态库 (.a) 和 DLL (.so) 之间的区别?

coder 2023-04-24 原文

我参与了一些关于 Linux 库的辩论,并想确认一些事情。
据我所知(如果我错了,请纠正我,我稍后会编辑我的帖子),在构建应用程序时有两种使用库的方法:

  • 静态库(.a 文件):在链接时,将整个库的拷贝放入最终应用程序,以便库中的函数始终可供调用应用程序使用
  • 共享对象(.so 文件):在链接时,对象只是通过相应的头文件 (.h) 对其 API 进行验证。直到运行时才实际使用该库,在那里需要它。

  • 静态库的明显优点是它们允许整个应用程序自包含,而动态库的好处是可以替换“.so”文件(即:如果由于安全原因需要更新) bug),而无需重新编译基本应用程序。
    我听说有些人区分共享对象和动态链接库 (DLL),即使它们都是“.so”文件。在 Linux 或任何其他符合 POSIX 的操作系统(即:MINIX、UNIX、QNX 等)上进行 C/C++ 开发时,共享对象和 DLL 之间有什么区别吗?有人告诉我,一个主要区别(到目前为止)是共享对象仅在运行时使用,而 DLL 必须首先使用应用程序中的 dlopen() 调用打开。
    最后,我还听到一些开发人员提到“共享文件”,据我了解,它本身也是静态库,但从未被应用程序直接使用。相反,其他静态库将链接到“共享文件”以将一些(但不是全部)功能/资源从共享文件中提取到正在构建的静态库中。
    预先感谢大家的帮助。
    更新

    在向我提供这些术语的上下文中,实际上是一组必须学习 Linux 的 Windows 开发人员使用的错误术语。我试图纠正它们,但(不正确的)语言规范卡住了。
  • 共享对象:程序启动时自动链接到程序中的库,并作为独立文件存在。该库在编译时包含在链接列表中(即: LDOPTS+=-lmylib 用于名为 mylib.so 的库文件)。 该库必须在编译时和应用程序启动时存在。
  • 静态库:在构建时合并到实际程序本身的库,用于包含应用程序代码和构建程序时自动链接到程序的库代码的单个(较大)应用程序,以及包含两者的最终二进制文件主程序和库本身作为一个独立的二进制文件存在。该库在编译时包含在链接列表中(即:LDOPTS+=-lmylib 用于名为 mylib.a 的库文件)。 该库必须在编译时存在。
  • DLL:本质上与共享对象相同,但不是在编译时包含在链接列表中,而是通过 dlopen() 加载库。/dlsym()命令,以便在程序编译时不需要存在库。 此外,该库不需要(必须)在应用程序启动或编译时出现 ,因为目前只需要 dlopen/dlsym调用。
  • 共享存档:本质上与静态库相同,但使用“export-shared”和“-fPIC”标志编译。该库在编译时包含在链接列表中(即: LDOPTS+=-lmylibS 用于名为 mylibS.a 的库文件)。两者之间的区别在于,如果共享对象或 DLL 想要将共享存档静态链接到其自己的代码中并且能够使共享对象中的函数可供其他程序使用,而不是仅仅使用它们,则需要此附加标志DLL 内部。当有人为您提供静态库,而您希望将其重新打包为 SO 时,这很有用。 该库必须在编译时存在。

  • 额外更新
    DLL ”和“shared library ”之间的区别只是我当时工作的公司的(懒惰的,不准确的)口语(Windows开发人员被迫转向Linux开发,并且该术语卡住了),坚持到上面提到的描述。
    此外,在“共享文件”的情况下,库名称后面的尾随“S”文字只是该公司使用的约定,而不是一般行业使用的约定。

    最佳答案

    我一直认为 DLL 和共享对象只是同一事物的不同术语 - Windows 称它们为 DLL,而在 UNIX 系统上它们是共享对象,通用术语 - 动态链接库 - 涵盖两者(甚至函数在 UNIX 上打开一个 .so 在“动态库”之后被称为 dlopen())。

    它们确实只在应用程序启动时链接,但是您对头文件的验证概念是不正确的。头文件定义了编译使用库的代码所需的原型(prototype),但在链接时,链接器会查看库本身以确保它需要的函数确实存在。链接器必须在链接时在某处找到函数体,否则会引发错误。它也在运行时这样做,因为正如您正确指出的那样,自程序编译以来,库本身可能已更改。这就是 ABI 稳定性在平台库中如此重要的原因,因为 ABI 的变化会破坏针对旧版本编译的现有程序。

    静态库只是直接从编译器出来的目标文件包,就像你在项目编译过程中自己构建的那些一样,所以它们以完全相同的方式被拉入并提供给链接器,未使用的位是以完全相同的方式下降。

    关于c++ - 共享对象 (.so)、静态库 (.a) 和 DLL (.so) 之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9688200/

    有关c++ - 共享对象 (.so)、静态库 (.a) 和 DLL (.so) 之间的区别?的更多相关文章

    1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

      总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

    2. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

      在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

    3. ruby-on-rails - Rails 应用程序之间的通信 - 2

      我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

    4. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

      我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

    5. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

      我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

    6. Ruby 写入和读取对象到文件 - 2

      好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

    7. ruby - 通过 ruby​​ 进程共享变量 - 2

      我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

    8. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

      如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

    9. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

      我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

    10. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

      请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

    随机推荐