Allegro.cc - Online Community

Allegro.cc Forums » Installation, Setup & Configuration » DLL experiences

This thread is locked; no one can reply to it. rss feed Print
DLL experiences
amarillion
Member #940
January 2001
avatar

I've spent some time troubleshooting missing DLL problems and I have some questions as well as some experiences to share.

Point 1. First of all, when you don't have the right dlls on your system, you get an error like "allegro-5-monolith.dll not found". Then you copy that dll into your game.exe directory and all is well.

But I noticed that the error you get is not always the same. Sometimes the error looks more like this:

Error: the application was unable to start correctly (0xc0000142)

Which was something that threw me off. But it turned out that also in this case the solution was to add a missing dll. Why is the error sometimes explicit about which dll is missing, and sometimes so cryptic?

Point 2. (This is more a tip than a question) Adding DLLs one by one gets tedious. I was looking for a way to scan for all dependencies. The ldd command is available with MSYS2, but for me it only shows the resolved dlls. I.e. it shows the location of the dlls it uses, but it doesn't help you find missing dlls. And on the system where I compiled things, it didn't resolve those dlls so I didn't even have one working example to start from. So ldd appears to be rather useless for this task.

$ ldd mexica.exe
ntdll.dll => /c/windows/SYSTEM32/ntdll.dll (0x77130000)
kernel32.dll => /c/windows/system32/kernel32.dll (0x76f10000)
KERNELBASE.dll => /c/windows/system32/KERNELBASE.dll

After some trial an error I settled upon the following method. I created a script named gather-dlls.sh, and repeatedly run it on windows from msys2.
First it tries to copy a set of dlls from various locations, and then it checks the list (with objdump -p) for dependencies. If a dll is missing, edit the list of copy commands, and repeat. If a newly copied dll has more dependencies, then they will show up as missing on the next invocation.

#SelectExpand
1#!/usr/bin/bash 2 3BASE=/mingw64/bin 4cp /mingw64/x86_64-w64-mingw32/bin/allegro_monolith-5.1.dll . 5 6cp $BASE/libgcc_s_seh-1.dll . 7cp $BASE/libstdc++-6.dll . 8cp $BASE/libfreetype-6.dll . 9cp $BASE/libbz2-1.dll . 10cp $BASE/libharfbuzz-0.dll . 11cp $BASE/libglib-2.0-0.dll . 12cp $BASE/libogg-0.dll . 13cp $BASE/libpng16-16.dll . 14cp $BASE/libphysfs.dll . 15cp $BASE/libintl-8.dll . 16cp $BASE/libtheoradec-1.dll . 17cp $BASE/libvorbis-0.dll . 18cp $BASE/zlib1.dll . 19cp $BASE/libwinpthread-1.dll . 20 21for i in $(objdump -p *.exe *.dll | grep 'DLL Name:' | sort | uniq | sed "s/\s*DLL Name: //") 22do 23 if [ -e $i ] 24 then 25 echo "FOUND: $i" 26 else 27 echo "MISSING: $i" 28 fi 29done

Sample output:

#SelectExpand
1MISSING: ADVAPI32.dll 2FOUND: allegro_monolith-5.1.dll 3MISSING: comdlg32.dll 4MISSING: GDI32.dll 5MISSING: gdiplus.dll 6MISSING: KERNEL32.dll 7FOUND: libbz2-1.dll 8FOUND: libfreetype-6.dll 9FOUND: libgcc_s_seh-1.dll 10FOUND: libglib-2.0-0.dll 11FOUND: libharfbuzz-0.dll 12FOUND: libiconv-2.dll 13FOUND: libintl-8.dll 14FOUND: libogg-0.dll 15FOUND: libphysfs.dll 16FOUND: libpng16-16.dll 17FOUND: libstdc++-6.dll 18FOUND: libtheoradec-1.dll 19FOUND: libvorbis-0.dll 20FOUND: libwinpthread-1.dll 21MISSING: msvcrt.dll 22MISSING: ole32.dll 23MISSING: OPENGL32.dll 24MISSING: PSAPI.DLL 25MISSING: SHELL32.dll 26MISSING: SHLWAPI.dll 27MISSING: USER32.dll 28MISSING: WINMM.dll 29MISSING: WS2_32.dll 30MISSING: XINPUT1_3.dll 31FOUND: zlib1.dll

If you have any suggestions on better ways to do this then please let me know.

Point 3: So my final question is, do I need to include the system dlls? The previous code snippet is exactly how I'm now bundling my game, e.g. libvorbis-0.dll included, but USER32.dll not. I've included everything that is part of msys2, and excluded everything that is the windows system directory. Is that generally the thing to do? Can I expect e.g. msvcrt.dll to be present on every Windows installation out there?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Peter Hull
Member #1,136
March 2001

Point 2 - Remember Windows can load DLLs at runtime using LoadLibrary and others. That's why you need DependencyWalker as Edgar suggests, in the general case. I can't remember whether Allegro does or doesn't load DLLs at run-time, it seems to be something that happens for OpenGL quite a bit.

Point 3 - You can rely on User32 being there. MSVCRT (or whatever it's called this week) will probably be there but it's versioned and the user may not have the same version as you. The correct version that you used is installed as a 'redistributable' somewhere in your SDK directory so strictly you should bundle it with your program (or use the merge module in your installer if you're being fancy)

Elias
Member #358
May 2000

MSVCRT.DLL which mingw compiled .exes depend on is not versioned I think, only MSVCRT100.DLL and so on which MSVC compiled .exes depend on.

I don't think DependencyWalker knows anything about DLLs loaded at runtime - it will have the same information as objdump only.

--
"Either help out or stop whining" - Evert

torhu
Member #2,727
September 2002
avatar

Dependecy Walker has a profile mode which you use for detecting DLLs that are run-time linked.

amarillion
Member #940
January 2001
avatar

I'm trying dependency walker too and it's a handy tool. My ultimate goal is to check the compiled binaries automatically on a CI server. I see that dependency walker can work as a command-line utility too, so I will experiment with that.

I'm still not completely clear exactly which dependencies I can assume to be there. Elias is right in that I'm compiling with Mingw so I don't depend on any versioned msvc libraries. I'm currently taking this list for granted:

#SelectExpand
1ADVAPI32.dll 2comdlg32.dll 3GDI32.dll 4gdiplus.dll 5KERNEL32.dll 6msvcrt.dll 7ole32.dll 8OPENGL32.dll 9PSAPI.DLL 10SHELL32.dll 11SHLWAPI.dll 12USER32.dll 13WINMM.dll 14WS2_32.dll 15XINPUT1_3.dll

I haven't noticed any problems with run-time DLL loading yet.

Go to: