![]() |
|
DLL experiences |
amarillion
Member #940
January 2001
![]() |
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. 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: 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
![]() |
amarillion, There is a much easier way to find out which dlls your program depends on. Use Dependency Walker. It will tell you exactly which dlls it needs. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
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. -- |
torhu
Member #2,727
September 2002
![]() |
Dependecy Walker has a profile mode which you use for detecting DLLs that are run-time linked. |
amarillion
Member #940
January 2001
![]() |
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: 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. -- |
|