【问题标题】:Recompile MFC DLL while client exe is running在客户端 exe 运行时重新编译 MFC DLL
【发布时间】:2011-03-07 22:14:37
【问题描述】:

是否可以在其“客户端”可执行文件运行时重新编译 MFC DLL,并让可执行文件检测并获取新的更改?如果可能,那是愚蠢的吗?能够在不重新启动 exe 的情况下重新编译 DLL 将在我的编码工作流程中节省一些时间。我使用的是 Visual Studio 2008,代码是用原生 C++/MFC 编写的。我的代码更改完全包含在 DLL 中,而不是 EXE。

谢谢!

【问题讨论】:

    标签: c++ dll mfc


    【解决方案1】:

    不幸的是,除非可执行文件支持热交换 DLL,否则您无法执行此操作。 Windows 中的标准 DLL 加载机制将在进程开始时加载它,或者在第一次使用 DLL 导出的函数时加载它,并且不会观察文件的更改以重新加载它。此外,根据 DLL 的加载方式,文件可能会被锁定以进行更改。

    您必须在重新编译之前停止您的客户端可执行文件。

    【讨论】:

    • DLL 中的 "dynamic" 表示在运行时加载相关代码,而不是在编译时进行静态链接。这并不意味着“即时重新加载”。以您想要的方式热交换 DLL 存在很多问题,包括相当大的安全性和稳定性问题。 (想象一下恶意网页发现浏览器问题以在路径中的某处下载 dll 并且所有本地进程都会立即自动重新加载它:-))
    【解决方案2】:

    是的,这是可能的。您需要确保可执行文件显式加载您的 DLL(通过 LoadLibrary)。如果您的可执行文件隐式加载您的 DLL,您将遇到 Franci 描述的问题。

    在可执行文件运行时更新库:

    • 为暂存新版本的 DLL 定义一些约定。它可能位于单独的文件夹中,或者具有不同的文件名/扩展名。
    • 有一种方法可以检查 DLL 的新版本。这可能是对用户界面中某些特定手势的响应,或者您可以从后台线程监视目录的更改。
    • 当您看到新版本时,卸载旧版本 (FreeLibrary),然后将其删除并将新版本移动到所需位置并重新加载 (LoadLibrary)。

    如果您的 DLL 实现了任何 COM 对象,请告诉我,我会给您一些额外的提示。

    【讨论】:

    • 嘿,很棒的小费,吉姆!不幸的是,DLL 似乎是隐式加载的——经过近 10 年开发的代码库现在已达到 200 万+ SLOC,包括几​​十个 DLL 和 EXE。我怀疑我是否可以说服管理层允许这样的改变,以方便这个卑微的代码猴:)
    • 不幸的是,这还不够。新的 DLL 可能在不同的地址有它的功能。这还意味着您必须在每次 LoadLibrary 调用之后为您需要的所有功能调用 GetProcAddress。而且由于它是一个 MFC DLL,因此您通常无法控制它。
    • @MSalters,是的 - 另一个不使用 MFC 的原因。对于这类问题,直通式 COM 通常是更好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多