Very strange behaviour with QLibrary.
-
In order to get the videocameras list I try to use this function:
@ void MainWindow::on_pushButton_clicked() {
QLibrary Avicap("avicap32.dll");
typedef bool (*CapGetDriverDescription)(uint wDriverIndex, char *lpszName, int cbName, char *lpszVer, int cbVer);
CapGetDriverDescription capGetDriverDescription= (CapGetDriverDescription)Avicap.resolve("capGetDriverDescriptionA");
if (capGetDriverDescription) {
for (int count= 0; count< 2; count++) {
char szDeviceName[256];
char szDeviceVersion[256];
memset(szDeviceName, '\0', sizeof(szDeviceName));
memset(szDeviceVersion, '\0', sizeof(szDeviceVersion));
if (capGetDriverDescription(count, szDeviceName, sizeof(szDeviceName), szDeviceVersion, sizeof(szDeviceVersion))) {
ui->textEdit->append(QString(szDeviceName));
} else break;
}
}
}
@But the program goes to crash. A function that works but is very strange and horrible is this:
@ for (int count= 0; count< 10; count++) Enumerate(count);
void MainWindow::Enumerate(int index) { QLibrary Avicap("avicap32.dll"); typedef bool (*CapGetDriverDescription)(uint wDriverIndex, char *lpszName, int cbName, char *lpszVer, int cbVer); CapGetDriverDescription capGetDriverDescription= (CapGetDriverDescription)Avicap.resolve("capGetDriverDescriptionA"); if (capGetDriverDescription) { char szDeviceName[80]; char szDeviceVersion[80]; memset(szDeviceName, '\0', sizeof(szDeviceName)); memset(szDeviceVersion, '\0', sizeof(szDeviceVersion)); if (capGetDriverDescription(index, szDeviceName, sizeof(szDeviceName), szDeviceVersion, sizeof(szDeviceVersion))) { ui->textEdit->append(QString(szDeviceName)+ ", "+ QString(szDeviceVersion)); Sleep(10); } else ui->textEdit->append("Error!!!"); } }
@
Look: you have to query for ten times the function “capGetDriverDescriptionA” defining “QLibrary Avicap(“avicap32.dll”);” each time.
In “Enumerate” function you have to insert “Sleep(10);”.
Very strange but now works.What do you think about? There is a bug in QLibrary object?
-
I don't think this is a bug in QLibrary, since that essentially just wraps (under windows) LoadLibrary.
From the docs on capGetDriverDescription, it looks like you have to call it 10 times to make sure that you have accessed each driver, and check each return. It doesn't look like the drivers are enumerated sequentially.
BTW - if you want to do this in the Qt way - you should look at QCamera and specifically QCamera::availableDevices().
As for your crash, I don't see anything obvious. Are you doing this is separate threads ? -
[quote author="mrdebug" date="1368048986"]In “Enumerate” function you have to insert “Sleep(10);”.
Very strange but now works.[/quote]Sounds like a race condition (not sure where). -
I've tried in an empty project, using Windows Xp, mingw, Qt 4.8.4.
Have you got a webcam or a capture device in your pc?
Can you try for me? -
Solved with
@#ifdef Q_OS_WIN
#include "windows.h"
#define __T(x) L ## x
bool Enumerate(WORD index, QString &Name, QString &Version) {
typedef BOOL WINAPI capGetDriverDescription(WORD wDriverIndex, LPTSTR lpszName, INT cbName, LPTSTR lpszVer, INT cbVer);
capGetDriverDescription* capGetDriverDescriptionFunction= 0;
HINSTANCE Avicap32Dll= 0;
Avicap32Dll= LoadLibraryW(__T("avicap32.dll"));
if (Avicap32Dll) {
capGetDriverDescriptionFunction= (capGetDriverDescription*)GetProcAddress(Avicap32Dll, "capGetDriverDescriptionA");
if (capGetDriverDescriptionFunction!= 0) {
char lpszName[80];
char lpszVer[80];
if (capGetDriverDescriptionFunction(index, LPTSTR(lpszName), 80, LPTSTR(lpszVer), 80)) {
Name= QString(lpszName);
Version= QString(lpszVer);
FreeLibrary(Avicap32Dll);
return true;
}
}
FreeLibrary(Avicap32Dll);
}
return false;
}
#endif@Anybody can explain this row:
@#define __T(x) L ## x@
???