c++ windows qt plugins loadlibrary

c++ - Catching LoadLibrary() errores con gracia



windows qt (6)

A menos que adjunte un depurador a su proceso, no creo que pueda hacerlo. El mensaje que normalmente aparece cuando sucede esto es generado internamente por LoadLibrary. SetErrorMode se usa en muchas aplicaciones para inhibir mensajes de esta forma, estoy sugiriendo que en algún lugar de su marco de aplicaciones, su llamada SetErrorMode para inhibir el mensaje del sistema operativo.

La única aplicación que se ha visto generar sus propios mensajes detallados sobre las fallas de carga dll es MS DevStudio, que se adjunta como un depurador y, por lo tanto, tiene acceso a una secuencia especial de eventos de depuración.

Estoy trabajando en una pieza de software C ++ que se ejecuta en todas las versiones de Windows entre Windows XP y Windows Vista. En mi código, desarrollé una DLL que enlaza con una biblioteca estándar (la biblioteca Qt ). Una vez que se implementa mi software, no es inusual que el usuario no tenga exactamente la misma versión de Qt en su sistema, sino una configuración ligeramente diferente. Puede haber funciones deshabilitadas (por lo que su compilación Qt no exporta el mismo conjunto de símbolos) o la biblioteca podría incluso modificarse de forma que la biblioteca binaria sea incompatible con el original.

En algún momento, estoy cargando mi DLL a través de una llamada LoadLibrary (). Esto atrae cualquier biblioteca de Qt que esté en el sistema del usuario. Si tengo suerte, su compilación de Qt es compatible con lo que utilicé al desarrollar mis archivos DLL, por lo que LoadLibrary () tiene éxito. Sin embargo, dependiendo de los cambios que hicieron en su compilación Qt, la llamada LoadLibrary () a veces falla con

  • "El módulo especificado no se pudo encontrar."; esto generalmente sucede si su compilación Qt consiste en menos DLL que mi compilación Qt. Así que mi DLL intenta cargar, por ejemplo, QtFoo.dll, pero dado que este dll no forma parte de su compilación de Qt, falla la carga de mi DLL.
  • "El procedimiento especificado no se pudo encontrar."; esto generalmente sucede si cambian su compilación de Qt para que ciertas características estén deshabilitadas, lo que da como resultado menos símbolos exportados.

Mi pregunta es: ¿cómo puedo detectar estos errores con gracia? Correcto, simplemente estoy usando GetLastError () y luego imprimo cualquiera de los dos mensajes anteriores. Sin embargo, sería mucho más útil si supiera qué módulo no se pudo encontrar o qué procedimiento falta. Observé que cuando se ejecuta una aplicación en el explorador que enlaza con una DLL faltante, el explorador logra producir un buen ''La aplicación foo no se pudo cargar ya que falta la biblioteca requerida blah.dll''. ¿Hay alguna API disponible para obtener más información sobre por qué una llamada LoadLibrary () falló exactamente?


¿Puede ser más proactivo y verificar la versión de los binarios de QT que necesita antes de llamar a LoadLibrary ()? Luego, puede advertir a su usuario que no tiene la versión que necesita su aplicación, y tal vez incluso proporcionarle un enlace al punto de instalación.


Para ampliar la respuesta de jeffamaphone, puede intentar recuperar los detalles de la versión del archivo antes de llamar a LoadLibrary . Puedes hacer esto usando la siguiente función:

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; }

Luego puede verificar los números de versión mayor / menor contra los que está esperando.


Puede MapAndLoad de ImageHLP.DLL puede ayudar. Devuelve una estructura LOADED_IMAGE.


En algún momento, estoy cargando mi DLL a través de una llamada LoadLibrary (). Esto atrae cualquier biblioteca de Qt que esté en el sistema del usuario.

No hagas esto! El tipo de errores que tienes es del tipo afortunado, con la misma facilidad podría dañar la memoria y colgarse. La forma canónica de enviar una aplicación Qt es enviar los archivos DLL o vincular estáticamente. Consulte la guía de implementación de Qt en los archivos de ayuda.

Edición posterior:

Después de leer sus comentarios, todavía no recomiendo que use este enfoque, ya que no puede estar seguro de que los archivos DLL sean compatibles con los archivos binarios, incluso si se cargan, lo que podría ocasionar errores difíciles de rastrear.

Sin embargo, creo que podría interceptar las llamadas LoadLibrary y ver cuáles fallan. La biblioteca MS Detours se puede usar para esto. También vea esta pregunta .


También puede hacer que Windows lo compruebe usando un archivo de manifiesto. Este archivo contiene la información sobre los requisitos en las versiones de las bibliotecas usadas. La información más precisa y completa está en el sitio msdn .

Eche un vistazo a la respuesta a esta pregunta sobre cómo usar LoadLibrary con un archivo de manifiesto .

La documentación de Qt menciona brevemente el uso de un archivo de manifiesto para VS2005; para versiones anteriores, debería crearlo por su cuenta.