假设我有一个可执行文件:app.exe
我在这个可执行文件中使用了 2 个不同的 3rd 方 DLL:foo.dll bar.dll 并且应用程序必须隐式链接到这些 DLL,也就是说我不能使用 ::LoadLibrary 来加载它们。
(注意:不是我不能调用LoadLibrary,而是这些DLL需要静态链接(C++ DLLs with __declspec(dllexport)),所以我调用 LoadLibrary没有任何意义,因为可执行加载器已经调用了它。)
这两个 DLL 确实 彼此之间没有任何依赖关系,也就是说,据我所知,它们的加载顺序是未定义的(并且 应该 是不相关的)。 (两者的依赖基本上都只在标准的windows dll(kernel32、msvcrt等)上
我现在有一个问题,我希望控制这些 DLL 的加载顺序,即我希望 foo.dll 在 bar 之前 总是 加载(DLL_PROCESS_ATTACH) .dll。
是否有可能告诉 Windows DLL 加载程序先加载一个 DLL?
编辑:要检查可执行文件的 DLL 加载顺序,可以使用 DUMPBIN.exe 实用程序:(只需启动 Visual Studio 命令提示符)
编辑:根据 this answer/this blog entry ,NT 加载程序确实按顺序遍历导入部分。 (这将导致 独立 DLL 按它们在导入部分中出现的顺序加载。)
C:\path\to\program> dumpbin /IMPORTS app.exe | grep -i \.dll
MSVCR80D.dll
KERNEL32.dll
OLEAUT32.dll
MSVCP80D.dll
foo.dll
bar.DLL
此输出意味着 MSVCR80D.dll(及其依赖项[a])将首先加载,而 bar.DLL 将最后加载。卸载将以相反的顺序进行。
我还没有发现如何影响这个加载顺序 ...
(注释)
[a] :这当然意味着例如kernel32.dll 会先加载,因为 msvcr80d.dll 会依赖 kernel32.dll。
根据一些要求,我为此添加了一个理由:(但是请,我仍然对此一般感兴趣。我知道如何解决 MFC 问题。)
它的调试版本中的 Microsoft MFC DLL 内置了内存泄漏检测。(据我所知,它与 _CrtSetDbgFlag 和相关工具使用的机制相同。)
MFC 调试 DLL 将在卸载时转储所有未释放的内存。现在,如果您的进程中有第二个 DLL,它独立于 MFC,并且这个第二个 DLL 在 DLL_PROCESS_DETACH 上释放内存,如果 MFC DLL 在另一个 dll 之前卸载,则 MFC 报告机制将报告错误的内存泄漏。
如果可以确保调试 MFC DLL 在所有独立 DLL 中最先加载/最后卸载,那么所有其他 DLL 本身就已经清理完毕,并且 MFC 不会报告错误泄漏。
最佳答案
这是一个想法:在 app.exe 的链接器选项中将它们标记为“延迟加载的 dll”怎么样?
延迟加载将允许您“静态”链接(即没有 LoadLibrary() 等),但不会加载 DLL 并在实际需要之前进行链接。
如果这是一个选项,那么(假设您可以等待很长时间,即不要在 main() 之前访问 foo/bar dll 函数),您可以在 main() 中访问一个函数(只需获取一个函数 ptr或其他东西)首先在 foo.dll 中加载它并绑定(bind)所有“静态”链接的函数?
(也许 LoadLibrary() 会在需要时触发相同的链接过程。不确定。不过在您的代码中看起来会更干净。)
关于c++ - 更改 Windows DLL 加载顺序? (加载顺序,不是搜索顺序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6371779/
如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我遵循了教程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
我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll
假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co