我已经将ffmpeg构建为DLL,并将其链接到我的应用程序,当DLL位于可执行文件文件夹中时,该应用程序可以正常运行。因为我想为不同的项目配置加载不同版本的ffmpeg,所以我需要将它们放置在.exe以外的文件夹中(例如,“ / bin / ffmpeg / config1”,“ / bin / ffmpeg / config2”等)。我知道如何在不修改环境PATH的情况下执行此操作的唯一方法是将DLL标记为“延迟加载”,然后在启动时通过LoadLibrary调用指定完整路径。
这对于其他DLL来说效果很好,但是对于FFMPEG,我很难使其正常工作。
我已经在vcxproj(实际上是在链接的.props文件中)中将DLL指定为DelayLoad:
<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被卸载?以及如何预防呢?
答案 0 :(得分:0)
我不知道这是否是眼前的问题,但是昨天我也发生了同样的事情。
原来是架构不匹配:我的程序是x64,DLL是用x86编译的。