Using QLibrary Avicap("avicap32.dll"); A very strange behaviour.
-
This function wants to get the cameras list.
@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;
}
}
}@If I call the external function "capGetDriverDescriptionA" from 0 to 2 all works well. I obtain the name of the two cameras correctly.
But if I go over 2 the program goes to crash.
According to msdn the function "capGetDriverDescriptionA" returns true if the camera exists and false if the camera does not exists. If I comment out the row "ui->textEdit->append(QString(szDeviceName));" the program does not go to crash and I can query the function from 0 to 9.Is this possible? How can I obtain the cameras list?
Now I'm using Qt 4.8.4 with mingw.
-
You could have a memory access error somewhere in your program. The error might even be from outside of your 'on_pushButton_clicked()' function -- these bugs are a pain to find because they don't cause crashes immediately. It's probably unrelated to Qt itself.
There are different things you can try to start debugging, such as
- Attach a debugger to your program, to get a stack trace of the crash -- What functions are called, leading up to the crash?
- Print out the contents of szDeviceName just before the crash site -- Does the output look correct?
Note: It is possible that when you start debugging, the crashes mysteriously disappear.
-
I'm not sure, actually. Have a look at http://qt-project.org/doc/qt-4.8/qlibrary.html#resolve -- it says[quote]The symbol must be exported as a C function from the library. This means that the function must be wrapped in an extern "C" if the library is compiled with a C++ compiler. On Windows you must also explicitly export the function from the DLL using the __declspec(dllexport) compiler directive[/quote]Does the DLL fit this criteria?
You can try to link the DLL at compile-time instead of using QLibrary, by including Vfw.h in your .cpp file, "adding the library to your .pro file":http://qt-project.org/doc/qt-4.8/qmake-project-files.html#declaring-other-libraries, and calling the function directly in your code.
-
Solved but a very horrible solution!
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.@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!!!");
}
}@ -
Yes, I did.
Here you are:@#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@