【问题标题】:Why are some delay load DLLs immediately unloaded with FFMPEG?为什么某些延迟加载 DLL 会立即用 FFMPEG 卸载?
【发布时间】:2018-09-24 22:26:41
【问题描述】:

我已将 ffmpeg 构建为 DLL 并将它们链接到我的应用程序,当 DLL 位于可执行文件夹中时,该应用程序运行良好。因为我想为不同的项目配置加载不同的ffmpeg版本,所以我需要将它们放在与.exe不同的文件夹中(即“/bin/ffmpeg/config1”、“/bin/ffmpeg/config2”等)。我知道如何在不修改环境 PATH 的情况下执行此操作的唯一方法是将 DLL 标记为“延迟加载”,然后在启动时通过 LoadLibrary 调用指定完整路径。

这适用于其他 DLL,但对于 FFMPEG,我无法使其正常工作。

我已经在我的 vcxproj(实际上是在链接的 .props 文件中)指定了要延迟加载的 DLL:

  <DelayLoadDLLs>
    avcodec-58.dll;avutil-56.dll;avformat-58.dll;swscale-5.dll;swresample-3.dll;
  </DelayLoadDLLs>

在启动时,我通过 LoadLibrary 加载它们:

LoadLibraryA("ffmpeg\\config1\\avcodec-58.dll");
LoadLibraryA("ffmpeg\\config1\\avutil-56.dll");
LoadLibraryA("ffmpeg\\config1\\avformat-58.dll");
LoadLibraryA("ffmpeg\\config1\\swscale-5.dll");
LoadLibraryA("ffmpeg\\config1\\swresample-3.dll");

奇怪的是,当我调用 LoadLibrary 时,它似乎正在加载它们,然后立即卸载其中一些:

'ffmpegtest.exe' (Win32): Loaded 'C:\ffmpegtest\bin\ffmpeg\medium\avcodec-58.dll'. Symbols loaded.
'ffmpegtest.exe' (Win32): Unloaded 'C:\ffmpegtest\bin\ffmpeg\medium\avcodec-58.dll'
'ffmpegtest.exe' (Win32): Loaded 'C:\ffmpegtest\bin\ffmpeg\medium\avutil-56.dll'. Symbols loaded.
'ffmpegtest.exe' (Win32): Loaded 'C:\ffmpegtest\bin\ffmpeg\medium\avformat-58.dll'. Symbols loaded.
'ffmpegtest.exe' (Win32): Unloaded 'C:\ffmpegtest\bin\ffmpeg\medium\avformat-58.dll'
'ffmpegtest.exe' (Win32): Loaded 'C:\ffmpegtest\bin\ffmpeg\medium\swscale-5.dll'. Symbols loaded.
'ffmpegtest.exe' (Win32): Loaded 'C:\ffmpegtest\bin\ffmpeg\medium\swresample-3.dll'. Symbols loaded.

因此,问题似乎与它选择卸载某些 dll 的事实有关。如果我根本不包含对 LoadLibrary 的任何调用,那么我在调用这些库的第一行代码中就会崩溃,这是 avutil-56.dll 中的一个函数。如果我包含对 LoadLibrary 的调用,那么前几个函数调用成功,然后我们在第一次调用未加载的库时崩溃,特别是 avcodec-58.dll 中的“av_codec_iterate()”。如果我将卸载的 DLL 复制到可执行文件夹,那么一切运行正常。

为什么有些 DLL 会被卸载?以及如何预防?

【问题讨论】:

  • 我认为您将动态加载与延迟加载 dll 混为一谈。
  • 需要详细说明吗?
  • 延迟加载意味着在调用它的第一个函数时加载dll。动态加载意味着在运行时加载一个 dll - 可能是在运行前不知道要加载哪个 * 特定 dll 时。
  • 是的,但延迟加载的另一个好处是您可以使用 LoadLibrary 手动加载 DLL(如果 exe 自动加载 DLL,则您无法执行此操作,它只使用路径)。
  • @Swordfish:延迟加载动态加载。这只是 MSVC 有用并隐藏了所有 LoadLibraryGetProcAddress 调用。

标签: c++ dll ffmpeg delay-load


【解决方案1】:

我不知道这是否是手头的问题,但我昨天也发生了同样的行为。

原来是架构不匹配:我的程序是 x64,而 DLL 是用 x86 编译的。

【讨论】:

    猜你喜欢
    • 2021-02-04
    • 2010-11-26
    • 1970-01-01
    • 2018-03-08
    • 1970-01-01
    • 2017-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多