[Solved] COM interface to CANoe



  • Hello,

    I try to program a COM interface to the COM-Server from CANoe. So the Qt project works as Client.

    Here is my code so far:

    3com_interface.pro
    @

    Add more folders to ship with the application, here

    folder_01.source = qml/3com_interface
    folder_01.target = qml
    DEPLOYMENTFOLDERS = folder_01

    Additional import path used to resolve QML modules in Creator's code model

    QML_IMPORT_PATH =

    If your application uses the Qt Mobility libraries, uncomment the following

    lines and add the respective components to the MOBILITY variable.

    CONFIG += mobility

    MOBILITY +=

    The .cpp file which was generated for your project. Feel free to hack it.

    SOURCES += main.cpp
    interface.cpp

    Installation path

    target.path =

    Please do not modify the following two lines. Required for deployment.

    include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
    qtcAddDeployment()

    HEADERS +=
    CANoe.h
    interface.h

    CONFIG += qaxcontainer
    @

    interface.cpp
    @
    #include "interface.h"
    #include <QDebug>
    #include "objbase.h"
    #include "CANoe.h"

    #include "windows.h"
    #include "winnls.h"
    #include "shobjidl.h"
    #include "objidl.h"
    #include "shlguid.h"

    #include "strsafe.h"

    Interface::Interface(QObject *parent) :
    QObject(parent)
    {
    }

    void Interface::trigger_slot(const QString &msg)
    {

    IApplication* pIApp;
    HRESULT result;
    
    result = CoInitialize(NULL);
    
    CLSID clsid;
    result = CLSIDFromProgID(L"CANoe.Application", &clsid);
    
    if(SUCCEEDED(result))
    {
        qDebug() << "CLSID saved";
    }
    
    const IID IID_IApplication = __uuidof(IApplication);
    
    result = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IApplication, (void**) &pIApp);
    
    if(SUCCEEDED(result))
    {
        qDebug() << "Connection established";
    }
    

    }
    @

    I get the following error:
    undefined reference to '_GUID const&_mingw_uuidof<IApplication>()' (line 37)

    I think the compiler has problems with the __uuidof operator. Are there other ways to get the IID of the CANoe COM interface?

    Or does someone have any experience or hints how to get access to a COM interface in Qt? I searched for hours in the Internet but doesn't find an example for Qt.
    Only some examples for Visual Studio with ATL. But I can't use ATL in Qt. Or are there any possibilities to use it in Qt?

    Thank you very much for all answers!



  • according to "__uuidof Operator":http://msdn.microsoft.com/en-us/library/zaah6a61.aspx you should compile with ole32.lib



  • you can use something like:

    @canoeAxObj = new QAxObject("CANoe.Application");
    CANoe::IApplication canoeapp = (CANoe::IApplication)canoeAxObj->querySubObject("Application");
    canoeapp->SetVisible(false);@

    where CANoe::IApplication comes from a header file generated with "dumpcpp tool":http://qt-project.org/doc/qt-5.1/activeqt/activeqt-dumpcpp.html with .tlb libid (from registry):

    i.e.

    D:\Qt\Qt5.1.1-MSVC2010\5.1.1\msvc2010_opengl\bin>dumpcpp input {7F31DEB0-5BCC-11
    d3-8562-00105A3E017B}

    this will generate a qt canoe.h (warning: different of canoe.h from CANoe installation), which you should add to your project; then with the code above is straight forward



  • Hello NicuPopescu,

    thank you for your answer. I've searched in the dcomcnfg after the IID of the CANoe interface.
    So I deleted line 37 of my code (see above) and added the following code:

    @
    IID IID_IApplication = {0x7F31DEB2-0x11d3-0x8562-0x00105A3E017B}
    @

    I think the result will be the same as your suggestion with the new header file?

    However I can start the program and CANoe starts automatically. So I think there is successfully a connection between CANoe and my Qt program.
    But in line 41 I have an if query whether the connection was successful. Unfortunately the program doesn't print "Connection established"

    Why is an error saved in HRESULT result? Does anybody has an idea?



  • bq. So I deleted line 37 of my code (see above) and added the following code:
    IID IID_IApplication = {0x7F31DEB2-0x11d3-0x8562-0x00105A3E017B}

    this is not safe, your app will not work with other CANoe package/version ... why not to link against ole32.lib abd use __uuidof()?

    check for possible CoCreateInstance() results as described in msdn ... loading CANoe application does not neccessarely mean you have got a pointer to its COM interface! I only can guess that pIApp is NULL, so no COM connection yet ...



  • How can I link to ole32.lib in Qt? I doesn't find it on my PC. Only the ole32.dll....

    What do you mean with the possible CoCreateInstance() results? Do you mean the error code saved in HRESULT result?



  • bq. How can I link to ole32.lib in Qt? I doesn’t find it on my PC. Only the ole32.dll….

    i.e. here is in C:\Program Files\Microsoft SDKs\Windows\v7.0A\Lib\
    better to copy it locally to your project in a "lib" folder and have in .pro file

    @LIBS += ../lib/ole32.lib@

    bq. What do you mean with the possible CoCreateInstance() results? Do you mean the error code saved in HRESULT result?

    yes

    L.E. I checked your initial code and it works ...



  • [quote author="NicuPopescu" date="1386863709"]i.e. here is in C:\Program Files\Microsoft SDKs\Windows\v7.0A\Lib\ better to copy it locally to your project in a "lib" folder and have in .pro file [/quote]

    I tried to add the library to my project:

    • I copied the Ole32.Lib out of the Microsoft SDK folder to my project directory

    • Then I added the following code to my pro file:

    @
    LIBS += C:/QtProject/3com_interface/libs/Ole32.Lib
    @

    But I get actually the same error:

    "undefined reference to '_GUID const& __mingw_uuidof<IApplication>()'

    Do I need some files more, for example the Ole32.dll?

    But I'm wondering that my code works correctly in your project. Could you post your code or your project so I can search for the differences?



  • Any ideas?

    I have still the same problem: How can I get the IID of a COM-Application to create the COM interface?

    There are two possibilities:

    1. Is there an alternative to __uuidof() to get the IID of the object?
    2. What do I need to add to my project, so I can use __uuidof() and how can I add this?

    Thank you for all answers so far!



  • bq. Do I need some files more, for example the Ole32.dll?

    dll will be found in system32, so no worry

    I don't know why it is so difficult for you to get the project compiled; just in case I paste exactly what I have in main window project:

    .pro file:

    @#-------------------------------------------------

    Project created by QtCreator 2013-12-13T16:39:39

    #-------------------------------------------------

    QT += core gui

    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

    TARGET = TestCANoeCOM
    TEMPLATE = app

    SOURCES += main.cpp
    mainwindow.cpp

    HEADERS += mainwindow.h

    FORMS += mainwindow.ui

    LIBS += ../TestCANoeCOM/lib/ole32.lib@

    path in LIBS depends on your projetc build directory in QtCreator's Projects panel

    in mainwindow.cpp

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QDebug>

    #include "C:\Program Files\Vector CANoe 7.5\Exec32\COMdev\canoe.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    IApplication* pIApp;
    HRESULT result;
    
    result = CoInitialize(NULL);
    
    CLSID clsid;
    result = CLSIDFromProgID(L"CANoe.Application", &clsid);
    
    if(SUCCEEDED(result))
    {
        qDebug() << "CLSID saved";
    }
    
    const IID IID_IApplication = __uuidof(IApplication);
    
    result = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IApplication, (void**) &pIApp);
    
    if(SUCCEEDED(result))
    {
        qDebug() << "Connection established";
    }
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }
    @

    nothing different to your first code ...

    bq. How can I get the IID of a COM-Application to create the COM interface?

    in registry HKEY_CLASSES_ROOT->PID (i.e CANoe.Application)->CLSID(Value)

    and in HKEY_CLASSES_ROOT->CLSID->Value(found above)->InprocServer32 , you can find more info on COM server registration like:
    LocalServer32=path to exe, ocx, dll into which your COM implementation resides

    hope it helps! :)



  • Hello NicuPopescu,

    I've found my mistake. Thank you for posting your code. You've helped me a lot!



  • you're welcome! :)

    hope the answers help other fellows here ...



  • HI



  • HI



  • I want to call a function from QT application in facet this function exist a CAPL script runing in Canalyzer I am using COM to get access to the function here my exemple but it doesnt work where is the problem any help plz

    this my code:

    ICAPL *pcapl;

    ICAPLFunction fn ;
    IApplication
    pIApp;

    HRESULT result,result1,result2, hresult,result3,result4,hr;
    IDispatch*CaplDisp,*CaplFn;
    WCHAR * szMember = L"Multiply";
    DISPID dispid;
    DISPPARAMS dispparams = {NULL, NULL, 0, 0};
    EXCEPINFO excepinfo;
    UINT nArgErr;
    CLSID clsid;

    result = CLSIDFromProgID(L"CANalyzer.Application", &clsid);
    const IID IID_CAPL =__uuidof(ICAPL);

    const  IID IID_CAPLFUNCTION =__uuidof(ICAPLFunction);
     const IID IID_IApplication =__uuidof(IApplication);
    

    result = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IApplication, (void**) &pIApp);

    result1=pIApp->get_CAPL(&CaplDisp);

               qDebug() << "Result_get_CAPL "<<result1 ;
    

    result2=CaplDisp->QueryInterface(IID_CAPL,(void**)&pcapl);
    qDebug() << "result2 "<<result2 ;

    VARIANT varResult;

    hr = CaplDisp->GetIDsOfNames(IID_CAPLFUNCTION, &szMember, 1, CLSCTX_LOCAL_SERVER, &dispid);
    qDebug() << "hr"<<hr ;
    if (SUCCEEDED(hr)) {
    hr = CaplDisp->Invoke(1,IID_CAPL, CLSCTX_LOCAL_SERVER,DISPATCH_METHOD,&dispparams, &varResult, NULL, NULL);
    }


Log in to reply
 

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