我正在开发一款可在Windows XP和Windows Vista之间的所有Windows版本上运行的C ++软件。在我的代码中,我开发了一个链接标准库(Qt library)的DLL。一旦部署了我的软件,用户在他的系统上没有完全相同的Qt构建,但配置略有不同并不罕见。可能有禁用的功能(因此它们的Qt构建不会导出相同的符号集),或者甚至可能以使库二进制文件与原始文件不兼容的方式更改库。
在某些时候,我正在通过LoadLibrary()调用加载我的DLL。这可以吸引用户系统上的任何Qt库。如果我很幸运,他们的Qt构建与我在开发DLL时使用的内容兼容,因此LoadLibrary()成功。但是,根据他们对Qt构建所做的更改,LoadLibrary()调用有时会失败并带有
我的问题是:我怎样才能优雅地捕捉到这些错误?对,我只是使用GetLastError(),然后打印上述两个消息之一。但是,如果我知道无法找到模块,或缺少哪个过程,那么很多会更有用。我注意到,当在资源管理器中运行一个链接缺少DLL的应用程序时,资源管理器设法产生一个很好的'由于缺少所需的库blah.dll而无法加载应用程序foo'。是否有一些API可用于获取有关LoadLibrary()调用失败原因的更多信息?
答案 0 :(得分:2)
在某些时候,我正在加载我的DLL 一个LoadLibrary()调用。拉了进来 无论Qt库在用户身上 系统
不要这样做!你遇到的那种错误是幸运的,同样容易损坏内存和崩溃。 运送Qt应用程序的规范方式是运送DLL或静态链接。查看帮助文件中的Qt部署指南。
稍后编辑:
在阅读您的评论后,我仍然不建议您使用此方法,因为即使加载了DLL也无法确定DLL是否是二进制兼容的,这可能导致难以跟踪错误。
尽管如此,我相信您可以拦截LoadLibrary调用并查看哪些调用失败。 MS Detours库可用于此目的。另请参阅this Stackoverflow问题。
答案 1 :(得分:2)
要扩展jeffamaphone的答案,您可以在致电LoadLibrary
之前尝试检索文件版本的详细信息。您可以使用以下功能执行此操作:
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;
}
然后,您可以检查主要/次要版本号码与您期望的版本号码。
答案 2 :(得分:1)
如果没有将调试器附加到您的进程,我认为您不能。通常在发生这种情况时弹出的消息由LoadLibrary在内部生成。 SetErrorMode在很多应用程序中被用来禁止这种形式的消息,我正在你的应用程序框架中的某个地方,它调用SetErrorMode
来禁止操作系统消息。
我见过的唯一应用程序生成自己的关于dll加载失败的详细消息是MS DevStudio - 它作为调试器附加,因此可以访问特殊的调试事件流。
答案 3 :(得分:1)
ImageHLP.DLL中的MapAndLoad
可以提供帮助。它返回一个LOADED_IMAGE结构。
答案 4 :(得分:0)
在调用LoadLibrary()之前,您是否可以更加主动和check the version所需的QT二进制文件?然后,您可以警告您的用户他们没有您的应用所需的版本,甚至可能提供指向他们的安装点的链接。
答案 5 :(得分:0)
您还可以使用清单文件对Windows进行检查。此文件包含有关已使用库版本的要求的信息。 msdn site上有更准确,更完整的信息。
查看this question about how to use LoadLibrary with a manifest file的答案。
The Qt documentation简要提到了VS2005的清单文件的用法;对于早期版本,您必须为自己创建它。