PDA

View Full Version : Accessing a QAxObject* from IDispatch* problem



vcernobai
26th January 2012, 19:51
Hello fellows,

I've been trying to solve an issue related to ActiveQt and COM objects for many hours, but still didn't found an answer to it. Would be nice to have some help from more experienced people with ActiveQt framework.
Here is the problem ... I have an external COM/dll on which I was using the dumpcpp tool to generate the .h and .cpp files.

This was my command: dumpcpp "C:\Program Files\CQG\CQGNet\Bin\CQGCEL-4_0.dll" -o CQGCEL-4_0

Next thing I was trying to treat in my SLOT(onSignal(QString,int,void*)) something that is emitted from the standard SIGNAL(signal(const QString&,int,void*)):


CQG_Tester::CQG_Tester() : cqgObj(new CQGCEL(this)) // cqgObj is a QAxObject from the external library.
{
connect(cqgObj, SIGNAL(signal(const QString&,int,void*)), SLOT(onSignal(QString,int,void*)));
connect(cqgObj, SIGNAL(CELStarted()), SLOT(requestDataSources()));
connect(cqgObj, SIGNAL(OnIdle()), SLOT(OnIdle()));
connect(cqgObj, SIGNAL(LineTimeChanged(const QDateTime&)), SLOT(LineTimeChanged(const QDateTime&)));
connect(cqgObj, SIGNAL(propertyChanged(const QString&)), SLOT(onPropertyChanged(QString)));
connect(cqgObj, SIGNAL(exception(int,const QString&,const QString&,const QString&)), SLOT(onException(int,QString,QString,QString)));

cqgObj->Startup();
}

My onSignal SLOT looks like this:


void CQG_Tester::onSignal(const QString & name, int argc, void * argv)
{
VARIANTARG *params = (VARIANTARG*)argv;
if(name == "InstrumentDOMChanged(IDispatch*,IDispatch*,IDispat ch*)") {

IDispatch * instrument_disp = params[argc-1].pdispVal;
//instrument_disp->AddRef(); // LINE A

ICQGInstrument instrument(instrument_disp, cqgObj); // QAxObject from the external COM/dll

for(int i = 0; i < 2; ++i) {

ICQGDOMQuotes * dom = (i == 0 ? instrument.DOMAsks() : instrument.DOMBids()); // QAxObject from the external COM/dll

cout << (i == 0 ? "Asks: " : "Bids: ");

const int count = dom->Count();
for(int j = 0; j < count; ++j) {
ICQGQuote * quote = dom->Item(j);
cout << quote->Price() << ',' << quote->Volume() << ';';
}
}
cout << endl;
}
}

As you can see in the code right above I'm trying to instantiate and use a QAxObject via a pointer to IDispatch*. From some reasons after the control flow leaves the onSignal method the application crashes somewhere in the imported dll.
But ... if I de-comment LINE A (instrument_disp->AddRef()) the program works fine, but it seems this produces a memory leak, because the memory used increases rapidly as this method is called very frequent.
There is also another strange internal Qt's debug message: Object::receivers: No such signal CQG::CQGCEL::InstrumentDOMChanged(IDispatch*,IDisp atch*,IDispatch*)
First of all I don't know why such a signal would not exist. I thought dumpcpp should handle properly this aspect since IDispatch* is a type supported by ActiveQt. Documentation says it is equivalent to an QAxObject*. It also seems that in the generated .cpp file the signal's signature is the following: InstrumentDOMChanged(ICQGInstrument*,ICQGDOMQuotes *,ICQGDOMQuotes*) which seems to be correct according to the library's documentation. Why would all three parameter types would have changed to IDispatch* while trying to emit somewhere the signal?
Also, I tried in onSignal() method to cast directly an IDispatch* object to an QAxObject*, but this seems NOT to work.

I have a feeling I'm missing a very little point, but hard for me to find out. Can anybody help on this please?

Many thanks in advance,
Victor