[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_01Additional 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.cppInstallation path
target.path =
Please do not modify the following two lines. Required for deployment.
include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
qtcAddDeployment()HEADERS +=
CANoe.h
interface.hCONFIG += 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 ...
-
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:
- Is there an alternative to __uuidof() to get the IID of the object?
- 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 = appSOURCES += main.cpp
mainwindow.cppHEADERS += 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 resideshope it helps! :)
-
you're welcome! :)
hope the answers help other fellows here ...
-
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); }