Acting on a QCamera object with an external function



  • Hi all !

    Thanks to @kshegunov's help, I managed to import external function from a dll to my project.

    I explain : I got a camera, and the dll, lib and headers for it. I'm buidling a soft in order to control it, so I made my own code, creating a QCamera object, and I would like to control this camera (Qcamera object) through the external functions from the dll.

    Here is my code extract :

    //ParametersDialog.cpp
    QLibrary myLib("D:\\my\\path\\to\\X.dll");
    
    ParametersDialog::ParametersDialog()
    {}
    
    void ParametersDialog::setCamera(QCamera *receiver) //There is no problem with the QCamera object
    {
        this->m_cameraInParameters=receiver;
    }
    
    void ParametersDialog::activateSetAutoWhiteBalance()
    {
       MyPrototype funcSetAutoWhiteBalance = (MyPrototype) myLib.resolve("X_SetAutoWhiteBalance");
    }
    
    //ParametersDialog.h
    #include <QMainWindow>
    #include <QLibrary>
    
    class ParametersDialog : public QMainWindow
    {
        Q_OBJECT
    public:
        ParametersDialog();
        ~ParametersDialog();
        void setCamera(QCamera *receiver);
    
    public slots:
        void activateSetAutoWhiteBalance();
    }
    
    //x.h (the dll's header, if I can name it like this ;) 
    typedef BOOL (*MyPrototype) (bool );
    

    So I would like to do something like : m_cameraInParameters.funSetAutoWhiteBalance(TRUE). Is that clear ?

    Have a nice day !

    EDIT : activateSetAutoWhiteBalance is connected to a QCheckbox like this connect(m_checkboxAutoWhiteBalance, SIGNAL(stateChanged(int)), this, SLOT(activateSetAutoWhiteBalance()));


  • Moderators

    It is not clear what these external functions do!
    Do these external functions know anything about QCamera or Qt at all?
    Is there a reason why you load the library manually using QLibrary? Why not just link against the library?



  • Hi @jsulm ! Thanks for your answer.

    These function know nothing about Qt, coming from a c++ code in VS2013.

    I don't know why exactly... i though it was a good way to do. (https://forum.qt.io/topic/64025/loading-function-from-a-dll)

    //.pro
    QT += core gui widgets multimediawidgets
    
    CONFIG += c++11
    
    TARGET = Camera
    CONFIG += console
    CONFIG -= app_bundle
    
    TEMPLATE = app
    
    SOURCES += main.cpp
    SOURCES += MainWindow.cpp
    SOURCES += ParametersDialog.cpp
    
    HEADERS += MainWindow.h \
        x.h
    HEADERS += ParametersDialog.h
    
    INCLUDEPATH += C:/external_library //modified
    LIBS +=  -lExternalLibrary //modified
    

  • Moderators

    It looks like you already linking against this library, so there is no need for

    QLibrary myLib("D:\\my\\path\\to\\X.dll");
    

    Well, then you cannot control the camera directly from these functions as they do not know anything about QCamera. You will have to write some glue code between those functions and the camera.



  • Hi again @jsulm !

    Yes, it was a lack of comprehension evidence :s

    So, I have to change this too no ? :

    void ParametersDialog::activateSetAutoWhiteBalance()
    {
       MyPrototype funcSetAutoWhiteBalance = (MyPrototype) myLib.resolve("X_SetAutoWhiteBalance");
        if (funcSetAutoWhiteBalance)
    
           funcSetAutoWhiteBalance(TRUE);
    }
    

    How ? Because if i try to just do funcSetAutoWhiteBalance(TRUE), compiler answer that it is not declared...Do I just have to declare it in my ParametersDialog.h ?

    "Well, then you cannot control the camera directly from these functions as they do not know anything about QCamera. You will have to write some glue code between those functions and the camera."
    Yes, @kshegunov said me the same thing. I'm a beginner, do you have some ideas in order to help me building this "glue code" ? :)

    Thanks a lot for your help, I know my ignorance is a bit irritating.


  • Qt Champions 2016

    Hello @Suji,
    If you're doing linking in your project file, as shown in post #3, you shouldn't want to do this at all:

    (MyPrototype) myLib.resolve("X_SetAutoWhiteBalance");
    

    Just as @jsulm noted, the resolution of symbols will be done for you by the loader. You just use the functions declared in the vendor's header directly:

    void ParametersDialog::activateSetAutoWhiteBalance()
    {
        X_SetAutoWhiteBalance(true);
    }
    

    Yes, @kshegunov said me the same thing. I'm a beginner, do you have some ideas in order to help me building this "glue code" ? :)

    This is an entirely different problem. Your vendor library (judging from the previous thread) has no notion of objects, so to use it as you'd use QCamera you'd have to write your own class and manage everything that comes with it. That said, something like this:

    class MyCamera : public QCamera
    {
        // ...
    }
    

    or, a backend for the QCamera class, although I've not worked with the multimedia module so I don't know how that's done exactly. You could search in the documentation of the multimedia module and see if it actually provides a way to plug-in your own camera controllers. Unfortunately, I can't see a (base) class that'd be useful for this purpose.

    Kind regards.



  • hi @kshegunov ;)

    Thank you for your answer! Oh, I understand the glue code logic better now.

    When i juste write :

    void ParametersDialog::activateSetAutoWhiteBalance()
    {
        X_SetAutoWhiteBalance(true);
    }
    

    A last question : The compiler say that X_SetAutoWhiteBalance is not defined in this scope. I have to define it in my ParametersDialog.h, into the class MyCamera : public QCamera for example, is it "normal" ?

    Thanks again !


  • Qt Champions 2016

    @Suji

    A last question : The compiler say that X_SetAutoWhiteBalance is not defined in this scope. I have to define it in my ParametersDialog.h, into the class MyCamera : public QCamera for example, is it "normal" ?

    Could you provide the full error you're getting? Can you check in the vendor's header whether that function is declared? - You'd expect to see something like (it may not be exactly as this, but similar):

    bool X_SetAutoWhiteBalance(bool);
    

    Kind regards.



  • The full error is :
    D:\path\ParametersDialog.cpp:158: error : 'funcSetAutoWhiteBalance' was not declared in this scope
    funcSetAutoWhiteBalance(TRUE);

    The vendor files are like this :

    //A.cpp
    #include <A.h>
    #include <B.h>
    pPluginGetAutoWhiteBalance	= (pfApiPluginGetAutoWhiteBalance)GetProcAddress(m_Plugin_HModule2, "X_GetAutoWhiteBalance");
    
    //A.h
    HMODULE	                        m_Plugin_HModule2;
    pfApiPluginSetAutoWhiteBalance	pPluginSetAutoWhiteBalance;
    
    //B.h
    typedef BOOL (*pfApiPluginSetAutoWhiteBalance) (bool );
    

    Is it everything needed ?


  • Qt Champions 2016

    @Suji
    Oh, man, this is terrible!
    Okay. I presume there are a number of those lines:

    typedef BOOL (*pfApiPluginSetAutoWhiteBalance) (bool );
    

    Create your own header, containing each of the functions' declarations by replacing the function pointer types with a nice usable name. It goes like this:
    For each:

    typedef BOOL (*pfApiPluginSetAutoWhiteBalance) (bool);
    

    You put in your header:

    BOOL X_SetAutoWhiteBalance(bool);
    

    This will create the declarations you need, also include windows.h on top (for all that uppercase defines). To use it, then include the header you've created, link the library (as you're doing) and use the functions. Only thing to watch out for is to wrap the declarations in your header in an extern "C".

    Suppose you have this:

    typedef BOOL (*pfApiPluginSetAutoWhiteBalance) (bool);
    typedef BOOL (*pfApiPluginSetZoomLevel) (int);
    

    You put it all in your header like this:

    #ifndef MY_EXTERNAL_LIBRARY_HEADER_H
    #define MY_EXTERNAL_LIBRARY_HEADER_H
    
    #include <windows.h>
    
    extern "C"
    {
        BOOL X_SetAutoWhiteBalance(bool);
        BOOL X_SetZoomLevel(int);
    }
    
    #endif // MY_EXTERNAL_LIBRARY_HEADER_H
    

    You won't be needing to do this tedious exercise for every typedef in the vendor's header, but only for the functions you'll be using.
    Then in your source you can use like this (supposedly your newly created header is named "myexternallibheader.h"):

    #include "myexternallibheader.h"
    // DO NOT INCLUDE THE VENDOR'S HEADER, ONLY YOUR OWN!
    
    // ... more code ...
    
    void ParametersDialog::activateSetAutoWhiteBalance()
    {
        X_SetAutoWhiteBalance(true);
    }
    

    Kind regards.



  • It's all very clear ! Let's go ! I'll give you news about it ;) Thanks a lot !


  • Qt Champions 2016

    @Suji

    ALTERNATIVELY

    Include the vendor's header and use the functions as they're resolved at runtime (quite suspiciously if I may add), like this:

    #include <vendorheader.h>
    
    // ... more code ...
    
    void ParametersDialog::activateSetAutoWhiteBalance()
    {
         pPluginGetAutoWhiteBalance(true);
    }
    

    But if you choose this approach, do not link the library in your project file:

    LIBS +=  -lExternalLibrary #< REMOVE THIS LINE IN THE .pro
    

    Note: However, this may lead to more problems, as you'd need to notify qmake to build the source file that resolves the symbols as well.

    Kind regards.



  • I'll try the first one firstly, seems to be a cleaner option, and I prefer to master all the code. :)



  • The first option work very well, thanks a lot !!

    Thanks again @kshegunov !



  • Well, the first goal is not resolved, I still have to connect my extern functions with my QCamera object. I'll try to change the approach, throwing the QCamera object, and use QMediaService (tanks for the idea @kshegunov). If someone has an idea for me, dont hesitate.

    Have a nice day !


Log in to reply
 

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