QLibrary fails to load or resolve, but WINAPI finds the modules
-
Problem surfaced during conversion to Qt5.5 from Qt4.8.5. Using Visual Studio 2013. Application has been running since Qt ver 3. I have 5 DLLs that I present to users, and they will pick one at a time to use. On starting the main dialog, I must load the DLL files that have been copied into a 'plugins' folder that is a subfolder of where the program is installed. So, first I look for all the .dll files and attempt to load each, trying also to resolve several of the standard callbacks. Again, this worked fine for years in Qt4.1+. But now I must use this odd sequence of coding to make the Qt reolve() function find the callbacks:
Thelst
variable contains the list of 5 dll files...while ( it!=lst.end() ) { gmv = 0; gmn = 0; gmt = 0; // QDir thisFile(QString("%1/%2").arg(dir.path()).arg((*it).baseName())); qDebug() << "Testing file " << QString("%1/%2").arg(dir.path()).arg((*it).baseName()).toLatin1(); fLibrary.setFileName((*it).fileName());// QString("%1/%2").arg(dir.path()).arg((*it).baseName())); // fLibrary.load(); gmv = (GET_MODULEVER)fLibrary.resolve((*it).fileName(), "GetModuleVer"); gmn = (GET_MODULENAME)fLibrary.resolve((*it).fileName(), "GetModuleName"); gmt = (GET_MODULETYPE)fLibrary.resolve((*it).fileName(), "GetModuleType"); if (!fLibrary.isLoaded()){ qDebug() << "Error loading: " << fLibrary.errorString() << " trying WINAPI"; HMODULE hmod = LoadLibrary(QString("%1/%2").arg(dir.path()).arg((*it).fileName()).toLatin1()); if (hmod) { qDebug() << "loaded successfully with LoadLibraryEx"; } else { DWORD errorMessageID = ::GetLastError(); if (errorMessageID) { LPSTR messageBuffer = nullptr; size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); std::string message(messageBuffer, size); //Free the buffer. LocalFree(messageBuffer); qDebug() << "failed to load with LoadLibraryEx"; qDebug() << message.c_str(); } } } gmv = (GET_MODULEVER)fLibrary.resolve((*it).fileName(), "GetModuleVer"); gmn = (GET_MODULENAME)fLibrary.resolve((*it).fileName(), "GetModuleName"); gmt = (GET_MODULETYPE)fLibrary.resolve((*it).fileName(), "GetModuleType");
The second round of
fLibrary.resolve()
succesfully finds the callbacks. I dont like this, because it uses the WinAPI to force the dll to be loaded. I would rather just use QLibrary.Why is this happening in Qt5.5?
-
Does (*it).fileName() return an absolute path to the library?
-
(*it).fileName()
returns only the file name portion, with extension, e.g. BIPSOpCirc.dll.(*it).baseName()
returns file name excluding path and extension, e.g BIPSOpCirc. Documentation suggest NOT using the file extension, to make things OS portable, though this program so far only runs in Windows. I have tried using both full path (the comment following thefLibrary.setfileName((*it).fileName())
, fileName only and baseName only. They all behave the same, the first call tofLibrary.resolve
gives null pointers, whereas the second, after the call to WinAPI to open the dll, gives a pointer to the callback.