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.


  • Moderators

    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 tried the function in a new empty project but does not work.
    Do you think that mingw is the cause?


  • Moderators

    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!!!");
    }
    }@



  • HI there,

    Im currently getting the very same behaviour, but thing is this little "Sleep(10)" doesn't fix the problem for me.

    Does someone have a clue of what could possibly cause this?

    @mrdebug did you find out another way of doing this?



  • 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@



  • Great that's very useful, thank you.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.