C :即使缺少第三方DLL,也允许程序运行

C++: allow program to run even if 3rd party DLL is missing?

本文关键字:许程序 程序 运行 DLL 第三方      更新时间:2023-10-16

我有一个C 应用程序,该应用程序与某些第三方动态库链接。我的某些主要类从这些库中继承,并向这些库进行函数调用。我的应用程序在理论上不包含这些库的情况下工作(即,如果我手动删除与这些库有关的所有代码和参考文献,它将仍然有效),这只是功能上的限制。如果我能够制作一个类比,请想象我已经创建了一个Windows Notepad克隆,并包括一个允许用户在文档中嵌入图片和视频的第三方库。

当我分发我的应用程序时,我的客户可能没有安装这些库。有没有办法让我的程序检测是否存在所需的DLL库,如果未安装所有相关代码,则可以忽略所有相关代码?

当前,如果我在未安装第三方库的情况下运行我的应用程序,则会显示与丢失的DLL和崩溃有关的错误。一个明显的解决方案是简单地发布我的应用程序的两个版本...一个没有外部依赖关系,但我想避免独立管理两个产品。

有这样的选项"延迟加载dll"

  1. 对于dll xxx.dll,您将链接器配置为使用" delayload"
  2. 直到您从DLL调用任何功能,它将不会加载,即使不存在DLL,您的应用程序也将成功启动
  3. 您使用loadLibrary检查xxx.dll是否可用。
  4. 如果负载失败 - 您使用xxx.dll禁用模块
  5. 如果LoadLibrary成功了 - 您将其卸载(您不需要动态加载 - 仅用于测试DLL的存在)并将库使用库(就像定期链接一样 - 无需使用任何XXX修改代码。DLL相关功能

在此处查看此答案:动态加载DLL

的函数
  1. 您基本上使用LoadLibrary加载DLL,结果将为是否已加载。

  2. 然后,您使用getProcaddress获取功能。

如果要分发应用程序的二进制文件,则可以使用动态加载(在此处查看)

但是,如果您可以选择在客户端系统上构建应用程序,则可以使用cmake并设置编译标志,如果找不到所需的库。然后,您的代码可以按照此标志的值行为(即,这样的方式,您就有有关该库存在的天气信息是否存在于您的代码中)

加载动态lib或注入过程,或者...可以使用此后使用:

    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
    inj_hModule = hModule;
    DisableThreadLibraryCalls(hModule); // Disable DllMain calls for DLL_THREAD_*
    HANDLE hThreadProc = CreateThread(nullptr, NULL, LPTHREAD_START_ROUTINE(ThreadProc), hModule, NULL, nullptr);
    CloseHandle(hThreadProc);
    Beep(2000, 500);
}
if (ul_reason_for_call == DLL_PROCESS_DETACH)
{
    Beep(2000, 500);
    FreeLibraryAndExitThread(hModule, 0);
    // exit this thread
    ExitThread(0);
}

好吧,您应该修改软件体系结构,并遵循Martin Fowler介绍的插件设计模式
尽管它非常相似,但您不希望这种情况的动态链接。

涉及C 中的实现,这基本上意味着您引入抽象接口首先

 struct Foo {
     virtual void Bar() = 0;
     virtual ~Foo() {}
 };

和查找合适的实现,并在运行时与共享库一起 1

共享库实现的导出接口需要匹配您的抽象接口声明。

您可以使用工厂进行查找,加载共享库并创建实现的实例。

这是一些更多信息,其中OS功能在动态加载和绑定插件中涉及。


1)请注意,如果您正在积极加载它们,则共享库不需要具有扩展名.dll.so

我的建议是仔细划分取决于该dll的代码。在项目的那部分中设计一个干净的接口,可以轻松地加载(负载Library),并且在程序的主要部分中与您与您互动的任何类中的任何类都具有纯虚拟接口(无DLL导出)。理想情况下,它具有纯函数接口,因为它们是最稳定的。

现在, dll可以取决于第三方dll。您的主代码通过手动加载并优雅地处理负载故障来调用您的"包装" DLL。

这比使用未为此设计的DLL更容易,您可以在不安装/卸载第三方DLL的情况下进行实验。