1

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?

alvion
  • 1,963
  • 3
  • 15
  • 23
  • I think you're mixing up dynamic loading vs. delayed loading of dlls. – Swordfish Sep 24 '18 at 22:31
  • Care to elaborate? – alvion Sep 24 '18 at 22:35
  • Delay loaing means the dll is loaded when the first function of it is called. Dynamic loading means to load a dll at runtime - Probably when it is not known before runtime \*which\* specific dll to load. – Swordfish Sep 24 '18 at 22:41
  • Right, but an added benefit of delay load is that you can load the DLL manually, with LoadLibrary (something you can't do if the exe loads the DLLs automatically, which only uses the Path). – alvion Sep 24 '18 at 23:01
  • 1
    @Swordfish: Delay-loading **is** dynamic loading.It's just MSVC being helpful and hiding all the `LoadLibrary` and `GetProcAddress` calls. – MSalters Sep 24 '18 at 23:25

1 Answers1

0

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.

Belgorath
  • 66
  • 6