【问题标题】:DLL swapping in c, am I doing it wrong?在c中交换DLL,我做错了吗?
【发布时间】:2016-09-17 14:28:18
【问题描述】:

因此,我希望能够在运行时更改应用程序的行为,而无需使用任何外部脚本语言。为了实现这一点,我尝试使用 DLL。我有类似的东西:

begin program;
load dll and function pointers;
init_func_ptr();
loop:
    if(compiled_new_version)
    {
        pause threads;
        unload dll;
        overwrite expired dll with new dll;
        load dll and function pointers;
        resume threads;
    }
    update_func_ptr(state);

最初我没有任何问题。但是,一旦我编写了一些实际代码,我在重新加载 dll 后就开始崩溃。只有我手动导出/重新加载的函数指针是“初始化”和“更新”。

关于我遇到的崩溃的一些信息。它在不知名的地方崩溃,调用堆栈中有一堆地址为“0xCDCDCDCD”的条目(值得一提的是,当我使用 Visual Studio 作为调试器并且应用程序在调试模式下编译时会发生这种情况)。

我认为发生的情况是,当我暂停线程时,其中一个或多个线程正在过期 dll 中执行一些代码,因此当我卸载该 dll 并恢复线程时,它们会导致崩溃。

我该如何解决这个问题?

【问题讨论】:

标签: c windows dll reloading


【解决方案1】:

您可能需要在 DLL 中编写代码以检查卸载 DLL 是否安全。例如,每个函数在进入时都会增加一个 DLL 全局变量,并在退出时将其递减。只有当它为零时才能安全卸载DLL。

您可能还需要编写代码来管理 DLL 处于“关闭模式”并且不应再被调用。例如,一个包含所有导出函数的包装器的包装器模块,它可以暂停调用线程,直到重新加载 DLL。请注意,此模块可能不能在 DLL 本身中。

我建议您首先制作一个框架应用程序来测试包含用于计数、同步和加载的最小功能的概念。

【讨论】:

  • 遗憾的是,我有等待 GetQueuedCompletionStatus 的 I/O 完成线程。将这些线程放在可执行文件中并确保这些线程在卸载时不调用任何 DLL 函数可以解决问题吗?
  • 似乎可以解决问题:只要不调用 DLL,就可以安全地卸载/重新加载它。请注意,0xcdcdccd 是典型的 VS 调试未初始化内存。
  • 好的,谢谢你的回答。将继续尝试然后报告。
  • 阿卡,别忘了卸载DLL后,DLL的所有数据都会丢失
  • 感谢您的回答。我已经完成了建议,并且在重新加载时不再崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 1970-01-01
  • 2011-12-25
  • 2019-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多