3

I have one big and difficult to understand problem with COM Server. I’m trying write client application to CANoe (application by Vector). They gave CANoe.tlb, CANoe.h and CANoe_i.cpp files but I use only CANoe.tlb via #import. All examples are in Visual Basic and I’m trying to write it in VC++ (console application). The problem is with inheritance. I.e. in help they wrote, that main object is Application and access to all methods, object events etc. is possible only via this object. All examples in Visual Basic are also simple, i.e:

Dim gCanApp As CANalyzer.Application
Set gCanApp = New Application
gCanApp.Open ("C:\Program Files\CANalyzer\Demo_CL\motbus.cfg")
gCanApp.CAPL.Compile
gCanApp.Measurement.Start

I’m sure that I’m making mistake but I have no idea where. In simply words I don’t have access to subobjects, their methods etc. I have only access to Application’s methods. For example I’d like to call method Start from Measurement object in this way: pApp->Measurement->Start() but it is impossible.

My source code:

#import "CANoe.tlb" //importing CANoe type library
#include "stdafx.h"
#include <atlbase.h> //COM Server methods
#include <iostream>

using namespace CANoe;
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
    /*This part is working perfectly: */
    CComPtr<IApplication> pApp = NULL;
    CComPtr<IMeasurement> measure = NULL;
    CComPtr<ICAPL> capl = NULL;
    CLSID clsid;
    IID iid;
    HRESULT result;

    /* Initialization COM library: */
    if (FAILED(CoInitialize(NULL))) 
    {
        cerr << "Initialization COM Library error" << endl;
        system("pause");
        return 1;
    }
    if((result = CLSIDFromProgID(L"CANoe.Application", &clsid)) != S_OK) 
    {
        cerr << "Problem with opening application" << endl;
        system("pause");
        return 2;
    }
    result = pApp.CoCreateInstance(clsid);  //Opening CANoe Application
    if(result != S_OK)
                cout << "pApp fault" << endl;

    pApp->Open(L"C:\\test\\test.cfg", FALSE, TRUE); //Opening test.cfg file
    /****************End of good part**********************/

    //pApp->Measurement->Start();//I'd like to use it in this way - compiler error: error C2039: 'Start' : is not a member of 'IDispatch'

    pApp->get_Measurement((IDispatch**)&measure);
    measure->Start();//Unhandled exception at 0x7711d78c in canoe.exe: 0xC0000005: Access violation writing location 0x7711d78c.
    CoUninitialize(); //Uninitialization COM Library
}

I attache CANoe COM Server files (it is legal from free Demo version): http://www.sendspace.com/file/5pgcou

P.S. Using COM Server is new for me so sorry for eventually stupid mistake. I was searching for any helpful information but I didn't find anything about using this COM Interface.

VividD
  • 10,456
  • 6
  • 64
  • 111
meler
  • 43
  • 2
  • 5
  • I don't believe that nobody can help me :( – meler Nov 26 '11 at 13:04
  • I can't compile your sample in pApp->Measurement->Start(), because Measurement retrun IDisptach object which not have Start method – Victor Nov 26 '11 at 13:55
  • You are right. I changed code in first post. Now it is compileable. So maybe you can propose sth how to use Measurement object with its methods. I opened CANoe.tlb with OLE-COM Object Viewer but these informations are not easy to understand for me. Can you see the solution for using another objects? Maybe I'm using pApp->GetMeasurement(IDispatch**) in wrong way. I attache help file about using CANoe COM Server : http://www.sendspace.com/file/7pqxyv – meler Nov 26 '11 at 15:48

1 Answers1

2

Try to change your code:

CComQIPtr<IMeasurement> measure;
CComPtr<IDispatch> measureDisp;

pApp->get_Measurement(&measureDisp);
measure = measureDisp;
measure->Start();

Also don't forget to check results of called methods.

Victor
  • 3,497
  • 3
  • 39
  • 51
  • It works perfectly :) Thank you a lot Victor!!! I didn't think about mixing CComQIPtr with CComPtr :) – meler Nov 26 '11 at 17:29
  • CComQIPtr just call QueryIterface and convert IDispatch to IMeasurement object. In COM you can't use static_cast for cast, you should use QueryInterface instead. – Victor Nov 26 '11 at 18:49