Я абсолютно новичок в программировании COM.
У меня большая проблема.Я пытаюсь обрабатывать события из приложения CANoe через COM-сервер.Сначала я попытался сделать это на родном C ++, но безрезультатно.Сейчас я пытаюсь это с помощью ATL.Я делаю что-то не так, но понятия не имею, что.Когда происходит событие, мое клиентское приложение приостанавливает себя и CANoe.После закрытия клиентского приложения CANoe работает нормально.Поэтому я знаю, что мое клиентское приложение обрабатывает события из CANoe, но не может его обслуживать.Комментированные части кода в моем исходном коде также использовались, но с теми же результатами.
#import "CANoe.tlb" //importing CANoe type library
#include "stdafx.h"
#include <atlbase.h> //COM Server methods
#include <iostream>
#include <atlhost.h>
using namespace CANoe;
using namespace std;
_ATL_FUNC_INFO infoZero = { CC_STDCALL, VT_EMPTY, 0, 0};
_ATL_FUNC_INFO infoOne = { CC_STDCALL, VT_EMPTY, 1, { VT_I4 } };
class CANoeComClient :
//IDispEventSimpleImpl<1, CANoeComClient, &__uuidof(_IMeasurementEvents)>,
//IDispEventSimpleImpl<2, CANoeComClient, &__uuidof(_IEnvironmentVariableEvents)>
IDispEventSimpleImpl<1, CANoeComClient, &__uuidof(_IApplicationEvents)>
{
IApplicationPtr pApp; //Pointer to the Application Object
IMeasurementPtr pMeasure; //Pointer to the Measurement object
_IMeasurementEventsPtr pMEvent; //Pointer to the Measurement's Events
IEnvironmentPtr pEnvironment; //Pointer to the Environment Object
IEnvironmentVariable2Ptr pEnvironmentVar; //Pointer to the Environment Variable Object
ICAPL2Ptr pCAPL; //Pointer to the CAPL Object
CLSID clsid; //globally unique identifier that identifies a COM class object
HRESULT result; //results of COM functions
public:
//typedef IDispEventSimpleImpl<2, CANoeComClient, &__uuidof(CANoe::_IEnvironmentVariableEvents)> EnvVarEventsHandler;
//typedef IDispEventSimpleImpl<1, CANoeComClient, &__uuidof(CANoe::_IMeasurementEvents)> MeasurementEventsHandler;
typedef IDispEventSimpleImpl<1, CANoeComClient, &__uuidof(CANoe::_IApplicationEvents)> ApplicationEventsHandler;
void __stdcall OnStart(void);
void __stdcall OnStop(void);
void __stdcall OnOpen(void);
void __stdcall OnQuit(void);
BEGIN_SINK_MAP(CANoeComClient)
//SINK_ENTRY_INFO(1, __uuidof(CANoe::_IMeasurementEvents), 0x02, OnStart, &info)
//SINK_ENTRY_INFO(1, __uuidof(CANoe::_IMeasurementEvents), 0x03, OnStop, &infoZero)
SINK_ENTRY_INFO(1, __uuidof(CANoe::_IApplicationEvents), 0x01, OnOpen, &infoZero)
SINK_ENTRY_INFO(1, __uuidof(CANoe::_IApplicationEvents), 0x02, OnQuit, &infoZero)
END_SINK_MAP()
void __stdcall OnChange();
/*
BEGIN_SINK_MAP(CANoeComClient)
SINK_ENTRY_INFO(2, __uuidof(CANoe::_IEnvironmentVariableEvents), 0x01, OnChange, &info)
END_SINK_MAP()*/
CANoeComClient(_bstr_t configPath);
HRESULT createEventConnection();
HRESULT startMeasurement();
HRESULT stopMeasurement();
};
void CANoeComClient::OnStart()
{
cout << "kurka wodna 1" << endl;
}
void CANoeComClient::OnStop()
{
cout << "kurka wodna 2" << endl;
}
void CANoeComClient::OnChange()
{
cout << "kurka wodna 2" << endl;
}
void CANoeComClient::OnOpen()
{
cout << "kurka wodna 1" << endl;
}
void CANoeComClient::OnQuit()
{
cout << "kurka wodna 1" << endl;
}
CANoeComClient::CANoeComClient(_bstr_t configPath)
{
/* Initialization COM library: */
if (FAILED(CoInitialize(NULL)))
{
cerr << "Initialization COM Library error" << endl;
system("pause");
return;
}
/* Actualization clsid variable with CANoe.Application path: */
if((result = CLSIDFromProgID(L"CANoe.Application", &clsid)) != S_OK)
{
cerr << "Problem with opening application" << endl;
system("pause");
return;
}
/*Opening CANoe application: */
result = pApp.CreateInstance(__uuidof(CANoe::Application));
if(result != S_OK)
{
cerr << "pApp fault" << endl;
return;
}
else
cout << "CANoe opened succesfully" << endl;
/* Opening CANoe configuration: */
result = pApp->Open(configPath, FALSE, TRUE); //Opening test.cfg file
if(result != S_OK)
{
cerr << "Opening configuration fault" << endl;
return;
}
else
cout << "Configuration loaded succesfully" << endl;
/*Definitions of all objects: */
//pMeasure.CreateInstance(__uuidof(CANoe::Measurement));
pEnvironment = pApp->Environment;
pEnvironmentVar = pEnvironment->GetVariable(L"env_ClientReq");
pCAPL = pApp->CAPL;
result = ApplicationEventsHandler::DispEventAdvise(pApp);
// result = MeasurementEventsHandler::DispEventAdvise(pMeasure);
//result = EnvVarEventsHandler::DispEventAdvise(pEnvironmentVar);
if(result != S_OK)
{
cerr << "Creating connection fault" << endl;
return;
}
else
cout << "Creating conenction succesfully" << endl;
}
HRESULT CANoeComClient::startMeasurement()
{
return pMeasure->Start();
}
HRESULT CANoeComClient::stopMeasurement()
{
return pMeasure->Stop();
}
int _tmain(int argc, _TCHAR* argv[])
{
int tmp = 0; //temporary variable to used to get envVar values
HRESULT result; //results of COM functions
CANoeComClient client(L"C:\\test\\test.cfg");
while(1);
}
Вот описание объекта измерения и события из средства просмотра объектов OLE-COM:
[
uuid(CD866FB6-44BF-11D3-8538-00105A3E017B),
helpstring("Measurement Class")
]
coclass Measurement {
[default] interface IMeasurement2;
[default, source] dispinterface _IMeasurementEvents;
};
[
odl,
uuid(A844C1E0-F5CE-11D3-8612-00105A3E017B),
helpstring("IMeasurement2 Interface"),
dual,
oleautomation
]
interface IMeasurement2 : IMeasurement {
[id(0x0000000a), propget, helpstring("property Running")]
HRESULT Running([out, retval] VARIANT_BOOL* pVal);
};
[
uuid(A844C1E0-F5CE-11D3-8612-00105A3E017B),
helpstring("IMeasurement2 Interface"),
dual
]
dispinterface IMeasurement2 {
properties:
methods:
[id(0x00000001), propget, helpstring("property Application")]
IDispatch* Application();
[id(0x00000002), propget, helpstring("property Parent")]
IDispatch* Parent();
[id(0x00000003), helpstring("method Start")]
void Start();
[id(0x00000004), helpstring("method Stop")]
void Stop();
[id(0x00000005), helpstring("method Step")]
void Step();
[id(0x00000006), helpstring("method Animate")]
void Animate();
[id(0x00000007), helpstring("method Break")]
void Break();
[id(0x00000008), helpstring("method Reset")]
void Reset();
[id(0x00000009), propget, helpstring("property AnimationDelay")]
long AnimationDelay();
[id(0x00000009), propput, helpstring("property AnimationDelay")]
void AnimationDelay([in] long rhs);
[id(0x0000000a), propget, helpstring("property Running")]
VARIANT_BOOL Running();
};
[
uuid(CD866FB7-44BF-11D3-8538-00105A3E017B),
helpstring("_IMeasurementEvents Interface")
]
dispinterface _IMeasurementEvents {
properties:
methods:
[id(0x00000001), helpstring("method OnInit")]
HRESULT OnInit();
[id(0x00000002), helpstring("method OnStart")]
HRESULT OnStart();
[id(0x00000003), helpstring("method OnStop")]
HRESULT OnStop();
[id(0x00000004), helpstring("method OnExit")]
HRESULT OnExit();
};
Прилагаю CANoe.tlb: http://www.sendspace.com/file/j2zloj
Спасибо за внимание, Дамиан