How to get a pointer to an object from a IDispatch pointer ?
Posted on 2004-04-30
Hope i post in the correct topic: I'm programming in C++ with COM to control Autocad.
For those not familar with Autocad programming, here is what is, i believe, a COM problem : at some part of my code, I have to transform a IAcadObjectPtr (derived from IDispatch) to a IAcadAttributeReferencePtr (derived from IAcadObject). This line does the job :
pAcadAttribRef = pAcadObject;
I have to execute this line very often in my program, and it's very slow : 1500 executions of that line take about 30 seconds on a P4 2.8 (with debug code, but release is not much faster) !
When i enter into that line, i see that's just a call to QueryInterface(). Is there a way to accelerate it ?
For those familar with Autocad programming, here is the all story :
Given a BlockReference, i need to get one of its AttributeReference from the Attribute tag (its name). I wrote this function :
IAcadAttributeReferencePtr DrvAcad::FindAttributeRefByTag(IAcadBlockReferencePtr pAcadBlockRef, const CString& strTag)
_variant_t arrayAttrib; // array of AttributeRef objects
long lbound, ubound;
IAcadAttributeReferencePtr AttribRef = NULL;
arrayAttrib = pAcadBlockRef->GetAttributes();
SafeArrayGetLBound(arrayAttrib.parray, 1, &lbound);
SafeArrayGetUBound(arrayAttrib.parray, 1, &ubound);
for (long i = lbound; i <= ubound; i++)
SafeArrayGetElement(arrayAttrib.parray, &i, &pObject);
AttribRef = pObject; // very slow !
if (AttribRef->GetTagString() == strTag)
GetAttributes() returns an array, but the array elements are not directly AttributeReferences; they are AcadObjects that i have to transform in AttributeReferences to finally be able to call AttribRef->GetTagString(). Anyway that's what i have been told, and i didn't find another way to get an attributeRef.
In some part of my program, i process about 300 block references and i have to call this function 5 times for each blockref (i need to set the values for 5 attributes). On a P4 2.8Ghz it takes almost 1 minute (with debug code, but release is not much faster). Much too slow because clients may have thousands of blocks to process !
By commenting some parts of the code and timing, i get to the conclusion that one of the main source of 'slowness' is the line AttribRef = pObject : it's responsible for about 30 secondes. When i enter into that line, i see that's just a QueryInterface().
I have to say i don't really understand the fine lines of COM programming (that would take me weeks of learning ...), i just try to pilot Autocad.
If someone has an explanation, or better a faster way for getting an AttributeRef ...