jjzjj

Windows DLL 和动态初始化顺序

coder 2024-06-10 原文

我有一些关于动态初始化(即 main 之前的构造函数)和 DLL 链接顺序的问题 - 适用于 Windows 和 POSIX。

为了方便讨论,我将定义几个术语:

Load-Time Libraries: libraries which have been "linked" at compile time such that, when the system loads my application, they get loaded in automatically. (i.e. ones put in CMake's target_link_libraries command).

Run-Time Libraries: libraries which I load manually by dlopen or equivalents. For the purposes of this discussion, I'll say that I only ever manually load libraries using dlopen in main, so this should simplify things.

Dynamic Initialization: if you're not familiar with the C++ spec's definition of this, please don't try to answer this question.

好的,假设我有一个应用程序 (MyAwesomeApp),它链接到一个动态库 (MyLib1),而动态库又链接到另一个库 (MyLib2)。所以依赖树是:

MyAwesomeApp -> MyLib1 -> MyLib2

对于这个例子,假设 MyLib1 和 MyLib2 都是加载时库。

上面的初始化顺序是什么?很明显,所有静态初始化,包括导出/导入函数的链接(仅限 Windows)将首先发生......但是动态初始化会发生什么?我希望整体排序:

所有导入/导出符号链接(symbolic link)
所有静态初始化
MyLib2 的所有动态初始化
MyLib1 的所有动态初始化
MyAwesomeApp 的所有动态初始化
MyAwesomeApp 的 main() 函数

但我在规范中找不到任何强制执行此操作的内容。我确实在 elf 上看到了一些暗示,但我需要在规范中找到保证,让我做我想做的事情。

只是为了确保我的思路清晰,我希望库加载的工作方式与 Python 中的“导入”非常相似,如果它还没有加载,它将被完全加载(包括任何初始化)在我做任何事情之前......如果它已经加载,那么我将链接到它。

举一个更复杂的例子来确保我的第一个例子的另一个定义没有产生不同的响应:

MyAwesomeApp 依赖于 MyLib1 和 MyLib2 MyLib1 依赖于 MyLib2

我希望进行以下初始化:

所有导入/导出符号链接(symbolic link)
所有静态初始化
MyLib2 的所有动态初始化
MyLib1 的所有动态初始化
MyAwesomeApp 的所有动态初始化
MyAwesomeApp 的 main() 函数

我希望得到任何帮助,指出规范表明它是这样的。或者,如果这是错误的,任何说明真正发生了什么的规范!

提前致谢!

-克里斯托弗

最佳答案

C++ 标准中没有规定动态链接的工作方式。

话虽如此,Visual Studio 附带了 C 运行时(也称为 CRT)源代码,您可以在 dllcrt0.c 中看到静态初始化程序在何处运行。

如果您考虑运行每个阶段需要满足哪些约束,您还可以推导出操作的相对顺序:

  1. 导入/导出解析只需要 .dll。
  2. 静态初始化只需要.dlls。
  3. 动态初始化要求为 .dll 解析所有导入。

第 1 步和第 2 步互不依赖,因此它们可以独立发生。第 3 步需要每个 .dll 的 1 和 2,因此它必须在 1 和 2 之后发生。

因此,满足上述约束的任何特定加载顺序都将是有效的加载顺序。

换句话说,如果您需要关心特定步骤的特定顺序,您可能正在做一些危险的事情,这些事情依赖于不会在操作系统的主要或次要修订版中保留的实现特定细节。例如,加载程序锁为 .dll 工作的方式在 Windows 的各种版本中发生了显着变化。

关于Windows DLL 和动态初始化顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24836194/

有关Windows DLL 和动态初始化顺序的更多相关文章

  1. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  2. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

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

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

  4. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  5. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  6. ruby - 为什么当我调用类的实例方法时,初始化不显示为方法? - 2

    我正在写一篇关于在Ruby中几乎一切都是对象的博客文章,我试图通过以下示例来展示这一点:classCoolBeansattr_accessor:beansdefinitialize@bean=[]enddefcount_beans@beans.countendend所以从类中我们可以看出它有4个方法(当然,除非我错了):它可以在创建新实例时初始化一个默认的空bean数组它可以计算它有多少个bean它可以读取它有多少个bean(通过attr_accessor)它可以向空数组写入(或添加)更多bean(也通过attr_accessor)但是,当我询问类本身它有哪些实例方法时,我没有看到默认

  7. ruby-on-rails - 在 RSpec 中,如何以任意顺序期望具有不同参数的多条消息? - 2

    RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)

  8. ruby-on-rails - 为什么在 Rails 5.1.1 中删除了 session 存储初始化程序 - 2

    我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于

  9. ruby - 在 Ruby 中动态创建数组 - 2

    有没有办法在Ruby中动态创建数组?例如,假设我想遍历用户输入的书籍数组:books=gets.chomp用户输入:"TheGreatGatsby,CrimeandPunishment,Dracula,Fahrenheit451,PrideandPrejudice,SenseandSensibility,Slaughterhouse-Five,TheAdventuresofHuckleberryFinn"我把它变成一个数组:books_array=books.split(",")现在,对于用户输入的每一本书,我想用Ruby创建一个数组。伪代码来做到这一点:x=0books_array.

  10. ruby - 是否可以将 IRB 提示配置为动态更改? - 2

    我想在IRB中浏览文件系统并让提示更改以反射(reflect)当前工作目录,但我不知道如何在每个命令后进行提示更新。最终,我想在日常工作中更多地使用IRB,让bash溜走。我在我的.irbrc中试过这个:require'fileutils'includeFileUtilsIRB.conf[:PROMPT][:CUSTOM]={:PROMPT_N=>"\e[1m:\e[m",:PROMPT_I=>"\e[1m#{pwd}>\e[m",:PROMPT_S=>"FOO",:PROMPT_C=>"\e[1m#{pwd}>\e[m",:RETURN=>""}IRB.conf[:PROMPT_MO

随机推荐