Hi.
I have a problem porting custom entity from ObjectArx 2012 to 2014. So I identified the problem by creating test entity project width ObjectArx wizard 2014 . BPTestLine is derived from AcDbLine and there are no other changes in wizard generated code other than this subGetGripPoints:
Acad::ErrorStatus BPTestLine::subGetGripPoints (
AcDbGripDataPtrArray &grips, constdouble curViewUnitSize, constint gripSize,
const AcGeVector3d &curViewDir, constint bitflags
) const {
assertReadEnabled () ;
//----- If you return eNotImplemented here, that will force AutoCAD to call
//----- the older getGripPoints() implementation. The call below may return
//----- eNotImplemented depending of your base class.
AcDbLine::subGetGripPoints (grips, curViewUnitSize, gripSize, curViewDir, bitflags) ;
AcGePoint3d pt1,pt2;
pt1 = startPoint();
pt2 = endPoint();
AcDbGripData *pGripData = new AcDbGripData();
pt1 = pt1+((pt2-pt1)*0.25);
pGripData->setGripPoint(pt1);
pGripData->setAppData((void*)4);//this 1/4 of the line and
grips.append(pGripData);
return Acad::eOk;
}
This code works fine in acad 2011/2012 but not in 2014
So now when I select this custom entity in Auotcad everything is fine and 4 point is displayed for BPTestLine, now if I move cursor to start or end or mid point the standart grip point context menu for line is displayed, but if I move my cursor to this 1/4 point the acad crash width 0x000...5 exception.
So what is changed in API?
Solved! Go to Solution.
Solved by artc2. Go to Solution.
Solved by igor.ivanov. Go to Solution.
Solved by Alexander.Rivilis. Go to Solution.
There is a risk of collision when you don't use a unique pointer for app data. Have you tested the same code with a pointer to a unique memory address instead of (void*)4? What is the stack trace when you break at the exception?
stacktrace at break from call stack window is :
> acdb19.dll!000007fed6352b16()
[Frames below may be incorrect and/or missing, no symbols loaded for acdb19.dll]
acdb19.dll!000007fed6991bee()
acdb19.dll!000007fed6b6b9ba()
accore.dll!000007fed8442714()
0000000039d08d40()
000007ffffb17390()
000000000027ebc0()
I modified code after it to put some unic pointer:
class CGripAppData
{
public:
CGripAppData(int id,CString str):m_ID(id),m_str(str){}
virtual ~CGripAppData(){};
inlineint index() const{return m_ID;}
inlinevoid setIndex(constint id){m_ID=id;}
inline CString GetStr() const { return m_str; }
inlinevoid setStr(CString val) { m_str = val; }
private:
int m_ID;
CString m_str;
};
....
Acad::ErrorStatus BPTestLine::subGetGripPoints (
AcDbGripDataPtrArray &grips, constdouble curViewUnitSize, constint gripSize,
const AcGeVector3d &curViewDir, constint bitflags
) const {
assertReadEnabled () ;
//----- If you return eNotImplemented here, that will force AutoCAD to call
//----- the older getGripPoints() implementation. The call below may return
//----- eNotImplemented depending of your base class.
AcDbLine::subGetGripPoints (grips, curViewUnitSize, gripSize, curViewDir, bitflags) ;
AcGePoint3d pt1,pt2;
pt1 = startPoint();
pt2 = endPoint();
AcDbGripData *pGripData = new AcDbGripData();
pt1 = pt1+((pt2-pt1)*0.25);
pGripData->setGripPoint(pt1);
//pGripData->setAppData((void*)4);
CGripAppData* pAppData = new CGripAppData(0,_T("sp"));
pGripData->setAppData((void*)pAppData);
//MyGripsData.append(pAppData); tried even static pointer array
grips.append(pGripData);
return Acad::eOk;
}
There is memory leak in this example becouse pointer never freed, but this should not be the case. The call stack in that case is:
> acdb19.dll!000007fed6352b1c()
[Frames below may be incorrect and/or missing, no symbols loaded for acdb19.dll]
acdb19.dll!000007fed6991bee()
acdb19.dll!000007fed6b6b9ba()
accore.dll!000007fed8442714()
000000003806e5e0()
000007ffffb17390()
00000000002fed10()
I do not know how this stack can help, becouse when I try to use debug symbols from http://symbols.autodesk.com/symbols there are no acdb19.pdb symols or I just missing somthing how it should be used.
I´m runing on Civil 2014 x64
In Visual Studio options Debugging->Native, enable 'Load DLL exports'. This should show whether the exception occurs due to accessing the grip data. Of course, it may be no help at all, but you won't know if you don't check.
Thank you its helped to see more info now the stack trace is this: but still not figuring out how to fix it...
> acdb19.dll!AcDbObjectId::objectClass() + 0x1ac bytes
[Frames below may be incorrect and/or missing, no symbols loaded for acdb19.dll]
acdb19.dll!AcDbImpLock::stripAutoLock() + 0xd3e bytes
acdb19.dll!AcDbImpPolyline::getParamsAtPoint() + 0x106a bytes
accore.dll!000007febe712714()
000000003949b120()
000007ffffb17390()
000000000031f000()
it comes when mose get on 1/4 grippoint of the line
As far as I remember CGripAppData have to be derived from AcRxObject or AcDbObject.
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Alexander, I think you remember wrong 😃 according to ObjectARX help:
"This method (setAppData) sets appData as the pointer to the application-specific data for this AcDbGripData object.
The application specific data is determined by the custom entity. AutoCAD does not access or modify the data. The host application uses a pointer to this data as an identifier for this grip when calling the AcDbEntity::moveGripPointsAt() function, so appData must not be null. "
So as far as I looked in the internet all examples was without deriving from any ARX "base" Class
I looked at ObjectArx 2008 grip sample to be sure and classes used there was not derived too.
And if it is changed in 2014 (the same code works fine in 2011/2012), why I can not find anything about it.
Any other proposals?
Thank you.
Igor
I don't think it's a good idea to assume that the documentation is correct. I would test Alexander's hypothesis.
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Based on the call stack, I doubt that the problem is with the app data. I suggest to upload the demo project so someone from Autodesk can have a look. Make sure you include details of your OS and AutoCAD 2014 version and architecture.
I think this is another bug in Acad core. I greated BPTestCircle derived from AcDbCircle entity and modified it subGetGripPoints function by adding one grip point and appData to it and it worked widhout crashing! There no context menu for circle when you put mouse on any grip point of it. I have very strong feeling, that the legs of this problem is growing from overruling AcDbLine grippoint handling by Autocad 2014. There was no context menu when mouse was over end or start point of the line in 2011/2012 and now it is there, and in my opinion it is overruled using same code as in polyline (line is simple polyline). This is huge problem to me is there any workaround, becouse my entity is derived from AcDbLine?
Acad::ErrorStatus BPTestCircle::subGetGripPoints (
AcDbGripDataPtrArray &grips, constdouble curViewUnitSize, constint gripSize,
const AcGeVector3d &curViewDir, constint bitflags
) const {
assertReadEnabled () ;
AcDbCircle::subGetGripPoints (grips, curViewUnitSize, gripSize, curViewDir, bitflags) ;
AcGePoint3d pt1,pt2;
pt1 = this->center();
AcDbGripData *pGripData = new AcDbGripData();
pt1 += AcGeVector3d(1,0,0)*this->radius()*0.25;
pGripData->setGripPoint(pt1);
//pGripData->setAppData((void*)4);
CGripAppData2* pAppData = NULL;
pAppData = new CGripAppData2(0,_T("sp"));
pGripData->setAppData((void*)pAppData);
grips.append(pGripData);
return Acad::eOk;
}
Yes Alexander you was right! I get it worked for AcDbLine when i added
class CGripAppData : public AcRxObject
....
So the case seems to be closed to me.
It is still strange that it is not required for AcDbCircle, but "when you know not to much you sleep better" =D
Thanks very much for help!
Igor
Need to trust people!
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
The AppData pointer doesn't need to point to a derived class when used with your own custom entity type because the generic grip mechanism truly treats it as an unknown pointer in that case (and that's what the documentation is documenting). BUT, if you are overruling an existing entity class's methods, then it must follow whatever requirements that entity type may have. Unfortunately, those requirements aren't documented.
Thanks Art for the accurate and concise explanation!
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn