False LoadLibrary () error

I am working on C ++ software that runs on all versions of Windows between Windows XP and Windows Vista. In my code, I developed a DLL that references a standard library ( Qt library ). Once my software is deployed, it is not unusual for a user to not have the same Qt build on his system, but in a slightly different configuration. Functions can be disabled there (therefore, their assembly Qt does not export the same character set), or the library can even be modified in ways that make the binary library incompatible with the original.

At some point, I load my DLL through a call to LoadLibrary (). This pulls any Qt library into the user system. If I'm lucky, their Qt build is compatible with what I used to design my DLLs, so LoadLibrary () completed successfully. However, depending on the changes made to their Qt assembly, calling LoadLibrary () sometimes fails with

  • "The specified module was not found."; this usually happens if their Qt build consists of less DLLs than my Qt build. Therefore, my DLL is trying to load, for example. QtFoo.dll, but since this dll is not part of their Qt assembly, loading my DLL does not work.
  • "The specified procedure was not found."; this usually happens if they change their Qt structure, so some functions are disabled, which leads to fewer exported characters.

My question is: how can I catch these errors gracefully? That's right, I just use GetLastError () and then print one of the two messages above. However, it would be much more useful if I knew which module could not be found or which procedure was missing. I noticed that when starting the application in Explorer, which is associated with the missing DLL, the explorer manages to get a good "Application foo cannot be loaded because the necessary library blah.dll is missing". Maybe some API is available to get more information on why the call to LoadLibrary () failed?

+6
c ++ windows plugins qt
source share
6 answers

Can MapAndLoad from ImageHLP.DLL help. It returns a LOADED_IMAGE structure.

+1
source share

At some point, I load my DLL through a call to LoadLibrary (). This pulls in any Qt library located on the system.

Do not do this! The kind of errors you have is a good one, and just as easily it can damage memory and crash. The canonical way to deliver a Qt application is to submit the DLL or link statically. Check out the Qt deployment guide in the help files.

Edit later:

After reading your comments, I still do not recommend using this approach, since you cannot be sure that the DLLs are compatible with binaries, even if they are loaded, which can make tracking errors difficult.

However, I believe that you can intercept the LoadLibrary calls and see which ones fail. You can use the MS Detours library for this. Also see this question in Stackoverflow.

+2
source share

To extend jeffamaphone's answer, you can try to get file version information before calling LoadLibrary . You can do this using the following function:

 BOOL GetFileDetails(LPCTSTR lpszPath, LPDWORD lpMajorVersion, LPDWORD lpMinorVersion) { DWORD dwVersionHandle; DWORD dwVersionSize = GetFileVersionInfoSize((LPTSTR)lpszPath, &dwVersionHandle); if (dwVersionSize == 0) return FALSE; LPBYTE lpVersion = new BYTE[dwVersionSize]; if (!GetFileVersionInfo((LPTSTR)lpszPath, dwVersionHandle, dwVersionSize, lpVersion)) { delete [] lpVersion; return FALSE; } VS_FIXEDFILEINFO *pVersionInfo = NULL; UINT nLength; if (!VerQueryValue(lpVersion, _T("\\"), (LPVOID *)&pVersionInfo, &nLength)) { delete [] lpVersion; return FALSE; } *lpMajorVersion = pVersionInfo->dwFileVersionMS; *lpMinorVersion = pVersionInfo->dwFileVersionLS; return TRUE; } 

Then you can check major / minor version numbers for the ones you expect.

+2
source share

Apart from the debugger for your process, I don't think you can. The message that usually appears when this happens is generated inside the LoadLibrary. SetErrorMode is used in many applications to block messages of this form, I assume that somewhere in the perspectives of your applications, its call to SetErrorMode blocks the OS message.

The only application that sees it generates its own detailed messages about dll loading crashes is MS DevStudio, which is connected as a debugger and therefore has access to a special stream of debugging events.

+1
source share

Can you be more active and check out the version of QT binaries you need before you call LoadLibrary ()? Then you can simply warn your user that they don’t have the version needed by your application, and maybe even provide a link to the installation point for them.

0
source share

You can also check Windows for this using the manifest file. This file contains information about the version requirements of the libraries used. More accurate and complete information is on the msdn website .

Take a look at the answer to this question on how to use LoadLibrary with a manifest file .

The Qt documentation briefly mentions the use of the manifest file for VS2005; for earlier versions you will have to create it yourself.

0
source share

All Articles