I've built ffmpeg as DLLs and linked them to my application, which runs fine when the DLLs are in the executable folder. Because I would like to load different builds of ffmpeg for different project configurations, I need to put them in different folders than the .exe (ie "/bin/ffmpeg/config1", "/bin/ffmpeg/config2", etc). The only way I know how to do this without modifying the environment PATH is to mark the DLLs as "delay load" and then specify the full path via LoadLibrary calls at startup.
This works fine for other DLLs, but for FFMPEG I'm having trouble getting it to work properly.
I've specified the DLLs to DelayLoad in my vcxproj (actually in a linked .props file):
<DelayLoadDLLs>
avcodec-58.dll;avutil-56.dll;avformat-58.dll;swscale-5.dll;swresample-3.dll;
</DelayLoadDLLs>
And at startup, I'm loading them via 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");
The strange thing is, when I make the LoadLibrary calls, it seems to be loading them and then unloading some of them immediately:
'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.
So, the problem DEFINITELY seems to be with the fact that it is choosing to unload some of the dlls. If I don't include any calls at all to LoadLibrary, then I get a crash in the very first line of code calling into these libraries, a function in avutil-56.dll. If I include the calls to LoadLibrary, then the first couple function calls succeed, and then we crash in the first call to an unloaded library, specifically "av_codec_iterate()" in avcodec-58.dll. If I copy the unloaded DLLs to the executable folder, then everything runs fine.
Why are some of the DLLs being unloaded? And how do I prevent it?
I don't know if this is the issue at hand, but the same behaviour happened to me yesterday.
Turns out it was an architecture mismatch: my program was x64, and the DLL was compiled with x86.