Author Topic: Deriving from AcDbPolyLine  (Read 7005 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6934
  • AKA Daniel
Deriving from AcDbPolyLine
« on: March 24, 2009, 01:45:15 AM »
I have a class that derives from AcDbployLine, (Not a custom Object)  after I add a few of these objects to the database then try to unload my ARX app, Acad crashes. 
Am I doing something wrong?

code I am using to add the entity
Code: [Select]
   AcDbObjectId pid;
   AcDbPolyline *p = new CrpRectangle(AcGePoint2d(0,0),400,400,PCode::kUpperRight);

   //closes the entity
   if (DatabaseTools::AddToCurrentSpace(p,pid) == Acad::eOk)
     acutPrintf(_T("\nok")
);


.h
Code: [Select]
#pragma once

#include "TypedValue.h"
#include "pcode.h"

#define ISEOK(statement)  { Acad::ErrorStatus st = (statement); if (st != Acad::eOk) return st; }

class CrpRectangle: public AcDbPolyline
{
public:
  CrpRectangle(DataMap &tvmap);
  CrpRectangle(const AcGePoint2d &pt, double width, double height, PCode::Location loc);
  virtual ~CrpRectangle(void);

public:
  Acad::ErrorStatus getWidth(double &width) const;
  Acad::ErrorStatus setWidth(double width);
  Acad::ErrorStatus getHeight(double &height) const;
  Acad::ErrorStatus setHeight(double height);
  Acad::ErrorStatus drawFrom(const AcGePoint3d &point);
  Acad::ErrorStatus drawFrom(const AcGePoint2d &point);
  Acad::ErrorStatus drawFrom(const AcGeVector2d &vec);
private:
  void calcLocation(const AcGePoint2d &startPoint, double width, double height, PCode::Location loc);

public:
 AcGePoint2d getPt1() const;
 AcGePoint2d getPt2() const;
 AcGePoint2d getPt3() const;
 AcGePoint2d getPt4() const;
 AcGePoint2d getMPB() const;
 AcGePoint2d getMPR() const;
 AcGePoint2d getMPT() const;
 AcGePoint2d getMPL() const;
 AcGePoint2d getCenter() const;

__declspec(property(get = getPt1))AcGePoint2d PT1;
__declspec(property(get = getPt2))AcGePoint2d PT2;
__declspec(property(get = getPt3))AcGePoint2d PT3;
__declspec(property(get = getPt4))AcGePoint2d PT4;
__declspec(property(get = getMPB))AcGePoint2d MPB;
__declspec(property(get = getMPR))AcGePoint2d MPR;
__declspec(property(get = getMPT))AcGePoint2d MPT;
__declspec(property(get = getMPL))AcGePoint2d MPL;
__declspec(property(get = getCenter))AcGePoint2d Center;
};

.cpp
Code: [Select]
#include "StdAfx.h"
#include "CrpRectangle.h"

CrpRectangle::CrpRectangle(DataMap &tvmap):AcDbPolyline(4)
{
  AcGePoint2d pt;
  double width;
  double height;
  short location;

  tvmap[1000].getPoint2d(pt);
  tvmap[1001].getDouble(width);
  tvmap[1002].getDouble(height);
  tvmap[1003].getShort(location);

  AcGePoint2d pt1 (pt.x + width,pt.y);
  AcGePoint2d pt2 (pt.x + width, pt.y + height);
  AcGePoint2d pt3 (pt.x, pt.y + height);
  if(this->isWriteEnabled())
  {
    this->addVertexAt(0,pt);
    this->addVertexAt(1,pt1);
    this->addVertexAt(2,pt2);
    this->addVertexAt(3,pt3);
    this->setClosed(Adesk::kTrue);
  }
  calcLocation(pt, width, height, (PCode::Location)location);
}

CrpRectangle::CrpRectangle(const AcGePoint2d &pt, double width, double height, PCode::Location loc):AcDbPolyline(4)
{
  AcGePoint2d pt1 (pt.x + width,pt.y);
  AcGePoint2d pt2 (pt.x + width, pt.y + height);
  AcGePoint2d pt3 (pt.x, pt.y + height);
  if(this->isWriteEnabled())
  {
    this->addVertexAt(0,pt);
    this->addVertexAt(1,pt1);
    this->addVertexAt(2,pt2);
    this->addVertexAt(3,pt3);
    this->setClosed(Adesk::kTrue);
  }
  calcLocation(pt, width, height, loc);
}

CrpRectangle::~CrpRectangle(void)
{
}

Acad::ErrorStatus CrpRectangle::getWidth(double &width) const
{
  Acad::ErrorStatus res;
  AcGePoint2d p0;
  AcGePoint2d p1;
  if((res = this->getPointAt(0,p0)) != Acad::eOk)
    return res;
  if((res = this->getPointAt(1,p1)) != Acad::eOk)
    return res;
  width = fabs(p0.x - p1.x);
  return Acad::eOk;
}

Acad::ErrorStatus CrpRectangle::setWidth(double width)
{
  Acad::ErrorStatus res;
  AcGePoint2d p0;
  AcGePoint2d p1;
  AcGePoint2d p2;

  if((res = this->getPointAt(0,p0)) != Acad::eOk)
    return res;

  if((res = this->getPointAt(1,p1)) != Acad::eOk)
    return res;

  if((res = this->getPointAt(2,p2)) != Acad::eOk)
    return res;

  p1.x = p0.x + width;
  p2.x = p0.x + width;

  if(!this->isWriteEnabled())
    return Acad::eNotOpenForWrite;

  if((res = this->setPointAt(1,p1)) != Acad::eOk)
    return res;

  if((res = this->setPointAt(2,p2)) != Acad::eOk)
    return res;

  return Acad::eOk;
}

Acad::ErrorStatus CrpRectangle::getHeight(double &height) const
{
  Acad::ErrorStatus res;
  AcGePoint2d p0;
  AcGePoint2d p4;
  if((res = this->getPointAt(0,p0)) != Acad::eOk)
    return res;
  if((res = this->getPointAt(4,p4)) != Acad::eOk)
    return res;
  height = fabs(p4.y - p0.y);
  return Acad::eOk;
}

Acad::ErrorStatus CrpRectangle::setHeight(double height)
{
  Acad::ErrorStatus res;
  AcGePoint2d p0;
  AcGePoint2d p2;
  AcGePoint2d p3;

  if((res = this->getPointAt(0,p0)) != Acad::eOk)
    return res;

  if((res = this->getPointAt(2,p2)) != Acad::eOk)
    return res;

  if((res = this->getPointAt(3,p3)) != Acad::eOk)
    return res;

  p2.y = p0.y + height;
  p3.y = p0.y + height;

  if(!this->isWriteEnabled())
    return Acad::eNotOpenForWrite;

  if((res = this->setPointAt(2,p2)) != Acad::eOk)
    return res;

  if((res = this->setPointAt(3,p3)) != Acad::eOk)
    return res;

  return Acad::eOk;
}

void CrpRectangle::calcLocation( const AcGePoint2d &startPoint, double width,
                                 double height, PCode::Location loc )
{
  AcGePoint2d point;
  switch ((int)loc)
  {
  case (int)PCode::kLowerLeft:
    {
      point = startPoint;
    }
    break;
  case (int)PCode::kLowerMid:
    {
      point = AcGePoint2d((startPoint[0] - (width / 2)), startPoint[1]);
    }
    break;
  case (int)PCode::kLowerRight:
    {
      point = AcGePoint2d((startPoint[0] - width), startPoint[1]);
    }
    break;
  case (int)PCode::kRightMid:
    {
      point = AcGePoint2d((startPoint[0] - width), (startPoint[1] - (height / 2)));
    }
    break;
  case (int)PCode::kUpperRight:
    {
      point = AcGePoint2d((startPoint[0] - width), (startPoint[1] - height));
    }
    break;
  case (int)PCode::kUpperMid:
    {
      point = AcGePoint2d((startPoint[0] - (width / 2)), (startPoint[1] - height));
    }
    break;
  case (int)PCode::kUpperLeft:
    {
      point = AcGePoint2d(startPoint[0], (startPoint[1] - height));
    }
    break;
  case (int)PCode::kLeftMid:
    {
      point = AcGePoint2d(startPoint[0], (startPoint[1] - (height / 2)));
    }
    break;
  }
  drawFrom(point);
}

Acad::ErrorStatus CrpRectangle::drawFrom( const AcGePoint3d &point )
{
  return drawFrom(AcGePoint2d(point.x,point.y));
}

Acad::ErrorStatus CrpRectangle::drawFrom( const AcGePoint2d &point )
{
  return drawFrom(point.asVector());
}

Acad::ErrorStatus CrpRectangle::drawFrom( const AcGeVector2d &vec )
{
  Acad::ErrorStatus res;

  if(!this->isWriteEnabled())
    return Acad::eNotOpenForWrite;

  AcGePoint2d pt0;
  AcGePoint2d pt1;
  AcGePoint2d pt2;
  AcGePoint2d pt3;

 ISEOK(this->getPointAt(0,pt0));
 ISEOK(this->getPointAt(1,pt1));
 ISEOK(this->getPointAt(2,pt2));
 ISEOK(this->getPointAt(3,pt3));
 ISEOK(this->setPointAt(0, pt0 + vec));
 ISEOK(this->setPointAt(1, pt1 + vec));
 ISEOK(this->setPointAt(2, pt2 + vec));
 ISEOK(this->setPointAt(3, pt3 + vec));

 return Acad::eOk;
}

AcGePoint2d CrpRectangle::getPt1(void) const
{
  AcGePoint2d pt;
  this->getPointAt(0,pt);
  return pt;
}

AcGePoint2d CrpRectangle::getPt2(void) const
{
  AcGePoint2d pt;
  this->getPointAt(1,pt);
  return pt;
}

AcGePoint2d CrpRectangle::getPt3(void) const
{
  AcGePoint2d pt;
  this->getPointAt(2,pt);
  return pt;
}

AcGePoint2d CrpRectangle::getPt4(void) const
{
  AcGePoint2d pt;
  this->getPointAt(3,pt);
  return pt;
}

AcGePoint2d CrpRectangle::getMPB() const
{
  AcGePoint2d pt0;
  this->getPointAt(0,pt0);
  AcGePoint2d pt1;
  this->getPointAt(1,pt1);
  return AcGePoint2d((pt1[0] - pt0[0]) / 2.0, pt0[1]);
}

AcGePoint2d CrpRectangle::getMPL() const
{
  AcGePoint2d pt1;
  this->getPointAt(0,pt1);
  AcGePoint2d pt4;
  this->getPointAt(3,pt4);
  return AcGePoint2d(pt1[0], (pt4[1] - pt1[1]) / 2.0);
}

AcGePoint2d CrpRectangle::getMPR() const
{
  AcGePoint2d pt2;
  this->getPointAt(1,pt2);
  AcGePoint2d pt3;
  this->getPointAt(2,pt3);
  return AcGePoint2d(pt2[0], (pt3[1] - pt2[1]) / 2.0);
}

AcGePoint2d CrpRectangle::getMPT() const
{
  AcGePoint2d pt3;
  this->getPointAt(2,pt3);
  AcGePoint2d pt4;
  this->getPointAt(3,pt4);
  return AcGePoint2d((pt3[0] - pt4[0]) / 2.0, pt3[1]);
}

AcGePoint2d CrpRectangle::getCenter() const
{
  AcGePoint2d pt1;
  this->getPointAt(0,pt1);
  AcGePoint2d pt2;
  this->getPointAt(1,pt2);
  AcGePoint2d pt4;
  this->getPointAt(3,pt4);
  return AcGePoint2d((pt2[0] - pt1[0]) / 2.0, (pt4[1] - pt1[1]) / 2.0);
}

added the arx for 07 (command is test)

pkohut

  • Guest
Re: Deriving from AcDbPolyLine
« Reply #1 on: March 24, 2009, 03:26:31 AM »
I have a class that derives from AcDbployLine, (Not a custom Object)  after I add a few of these objects to the database then try to unload my ARX app, Acad crashes. 
Am I doing something wrong?

The derived class is a custom object, it just happens that it doesn't override any of the
required virtual functions of a normal custom object.  So AcDbPolyline is doing all the
drawing, filing, selecting, etc.  Still the object is of type CrpRectangle and when
Autocad asks the object for its RTTI it's getting CrpRectangle which as long as your
application is loaded then there is a VTable entry for CrpRectangle's code.  Unload
your application, the object is still of type CrpRectangle, but the VTable entry is
no longer valid and causing the crash.

Only when the drawing is saved and reload is your CrpRectangle now truely an
AcDbPolyline object.

Paul

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6934
  • AKA Daniel
Re: Deriving from AcDbPolyLine
« Reply #2 on: March 24, 2009, 03:39:16 AM »
Ok that makes sense, I guess I should probably learn how to make a custom object the correct way , or redo my class so it creates a  polyline.

Thanks  :-)

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6934
  • AKA Daniel
Re: Deriving from AcDbPolyLine
« Reply #3 on: March 24, 2009, 03:53:14 AM »
I could always lock the application via acrxDynamicLinker->lockApplication();   :evil:

MickD

  • Gator
  • Posts: 3300
  • (x-in)->[process]->(y-out)
Re: Deriving from AcDbPolyLine
« Reply #4 on: March 24, 2009, 05:01:36 AM »
Pretty much what Paul said with the main point being that you can add objects to the database (as they derive from an AcDbObject therefore they pass the 'isA' test) but when the db fileout method is called it will crash as there is no function to handle the call.

For your Polyline object you simply call it's fileout() function in your custom fileout function and it will look after itself but for any custom data you will need to write the file out/in functions so it gets filed properly. Generally this isn't too hard as most data is doubles or text which you associate with an inbuilt db object to give it some 'intelligence' or custom modification or grip/snap behaviour, you just have to remember to reverse the order of filein and fileout operations if IRC.

All of this should be handled in a dbx dll with your custom behaviour that doesn't get filed out in an arx, of course your behavioural methods are in the dbx but the commands to make them happen reside in an arx typically.
hth.
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: ďTo attain knowledge, add things
every day; to obtain wisdom, remove things every day.Ē

MickD

  • Gator
  • Posts: 3300
  • (x-in)->[process]->(y-out)
Re: Deriving from AcDbPolyLine
« Reply #5 on: March 24, 2009, 05:04:09 AM »
There's a section in the doc's which covers the bare minimum requirements for filing objects and how to do it which isn't that hard, the hardest bit is the behavioural side of things (making them reliable/bugproof) IMO.
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: ďTo attain knowledge, add things
every day; to obtain wisdom, remove things every day.Ē

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6934
  • AKA Daniel
Re: Deriving from AcDbPolyLine
« Reply #6 on: March 24, 2009, 05:23:43 AM »
Thanks Mick,

Iíll to have a look at the docs on building custom objects,  I think there is a sample video out there as well.
I donít need to change the way the entity behaves, I just want to add my own way of constructing the object.
Locking the application seems to prevent AutoCAD from crashing, although it's probably a kludge  :|

Spike Wilbury

  • Guest
Re: Deriving from AcDbPolyLine
« Reply #7 on: March 24, 2009, 01:14:47 PM »
Also.... (and maybe this will help)

When you derive from AcDbPolyline (I have used for some of my custom objects) some of the methods will required the use of 'AcDbCurve' methods, in order to work.

MickD

  • Gator
  • Posts: 3300
  • (x-in)->[process]->(y-out)
Re: Deriving from AcDbPolyLine
« Reply #8 on: March 24, 2009, 03:25:38 PM »
...Locking the application seems to prevent AutoCAD from crashing, although it's probably a kludge  :|


Sorry Dan, I misunderstood you first question (I was thinking unloading the dwg), locking the app my stop it crashing but there's still a problem as you say.
Unloading the app doesn't file the object in/out so what happens when you try to save the file? If you want your object to be saved and read back in you will need to write the filer code, if not you'll probably have to destroy the objects before saving but that's also a bit of a kludge.
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: ďTo attain knowledge, add things
every day; to obtain wisdom, remove things every day.Ē

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6934
  • AKA Daniel
Re: Deriving from AcDbPolyLine
« Reply #9 on: March 24, 2009, 09:52:56 PM »
After additional testing, it seems everything works just dandy as long as the Arx stays loaded in the session where the object is created.
Saving, Closing, etc. all work. As Paul said, itís probably something to do with the VTable.

Spike Wilbury

  • Guest
Re: Deriving from AcDbPolyLine
« Reply #10 on: March 24, 2009, 11:11:11 PM »
After additional testing, it seems everything works just dandy as long as the Arx stays loaded in the session where the object is created.
Saving, Closing, etc. all work. As Paul said, itís probably something to do with the VTable.

There is a note every time you create a custom object added from the arxwizard.... for example:

Quote
#pragma once

#ifdef EZONEDBX_MODULE
#define DLLIMPEXP __declspec(dllexport)
#else
//----- Note: we don't use __declspec(dllimport) here, because of the
//----- "local vtable" problem with msvc. If you use __declspec(dllimport),
//----- then, when a client dll does a new on the class, the object's
//----- vtable pointer points to a vtable allocated in that client
//----- dll. If the client dll then passes the object to another dll,
//----- and the client dll is then unloaded, the vtable becomes invalid
//----- and any virtual calls on the object will access invalid memory.
//-----
//----- By not using __declspec(dllimport), we guarantee that the
//----- vtable is allocated in the server dll during the ctor and the
//----- client dll does not overwrite the vtable pointer after calling
//----- the ctor. And, since we expect the server dll to remain in
//----- memory indefinitely, there is no problem with vtables unexpectedly
//----- going away.
#define DLLIMPEXP
#endif

MickD

  • Gator
  • Posts: 3300
  • (x-in)->[process]->(y-out)
Re: Deriving from AcDbPolyLine
« Reply #11 on: March 25, 2009, 12:43:35 AM »
It looks like Luis has found a good clue!


After additional testing, it seems everything works just dandy as long as the Arx stays loaded in the session where the object is created.
Saving, Closing, etc. all work. As Paul said, itís probably something to do with the VTable.

hmm, it must be calling the derived class to file out the polyline, does it save your member data as well?
If so that's pretty spooky :)
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: ďTo attain knowledge, add things
every day; to obtain wisdom, remove things every day.Ē

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6934
  • AKA Daniel
Re: Deriving from AcDbPolyLine
« Reply #12 on: March 25, 2009, 01:10:18 AM »
After additional testing, it seems everything works just dandy as long as the Arx stays loaded in the session where the object is created.
Saving, Closing, etc. all work. As Paul said, itís probably something to do with the VTable.

There is a note every time you create a custom object added from the arxwizard.... for example:

Quote
#pragma once

#ifdef EZONEDBX_MODULE
#define DLLIMPEXP __declspec(dllexport)
#else
//----- Note: we don't use __declspec(dllimport) here, because of the
//----- "local vtable" problem with msvc. If you use __declspec(dllimport),
//----- then, when a client dll does a new on the class, the object's
//----- vtable pointer points to a vtable allocated in that client
//----- dll. If the client dll then passes the object to another dll,
//----- and the client dll is then unloaded, the vtable becomes invalid
//----- and any virtual calls on the object will access invalid memory.
//-----
//----- By not using __declspec(dllimport), we guarantee that the
//----- vtable is allocated in the server dll during the ctor and the
//----- client dll does not overwrite the vtable pointer after calling
//----- the ctor. And, since we expect the server dll to remain in
//----- memory indefinitely, there is no problem with vtables unexpectedly
//----- going away.
#define DLLIMPEXP
#endif



Thatís it, Thanks  Luis

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6934
  • AKA Daniel
Re: Deriving from AcDbPolyLine
« Reply #13 on: March 25, 2009, 01:11:15 AM »
It looks like Luis has found a good clue!


After additional testing, it seems everything works just dandy as long as the Arx stays loaded in the session where the object is created.
Saving, Closing, etc. all work. As Paul said, itís probably something to do with the VTable.

hmm, it must be calling the derived class to file out the polyline, does it save your member data as well?
If so that's pretty spooky :)

I wouldnít think it would save any member data, I only wanted to add my own constructor.  :mrgreen:

pkohut

  • Guest
Re: Deriving from AcDbPolyLine
« Reply #14 on: March 25, 2009, 01:23:35 AM »
hmm, it must be calling the derived class to file out the polyline,
If your saying its calling AcDbPolyline filers, that would be correct and is
be the expected behavior.

does it save your member data as well?
No can do, because the custom filer is not written.

Paul

pkohut

  • Guest
Re: Deriving from AcDbPolyLine
« Reply #15 on: March 25, 2009, 01:35:53 AM »
Good find Luis.  I couldn't put my finger on it yesterday when testing a custom DBX and
unloading it only to have the proxy graphics dialog pop up on the redraw.  I was trying
to think how AutoCAD could have caught that internally, but just couldn't come to
a good conclusion.  Since the sample Daniel provided is a part of an ARX app then
DLLIMPEXP = __declspec(dllimport).

Paul


After additional testing, it seems everything works just dandy as long as the Arx stays loaded in the session where the object is created.
Saving, Closing, etc. all work. As Paul said, itís probably something to do with the VTable.

There is a note every time you create a custom object added from the arxwizard.... for example:

Quote
#pragma once

#ifdef EZONEDBX_MODULE
#define DLLIMPEXP __declspec(dllexport)
#else
//----- Note: we don't use __declspec(dllimport) here, because of the
//----- "local vtable" problem with msvc. If you use __declspec(dllimport),
//----- then, when a client dll does a new on the class, the object's
//----- vtable pointer points to a vtable allocated in that client
//----- dll. If the client dll then passes the object to another dll,
//----- and the client dll is then unloaded, the vtable becomes invalid
//----- and any virtual calls on the object will access invalid memory.
//-----
//----- By not using __declspec(dllimport), we guarantee that the
//----- vtable is allocated in the server dll during the ctor and the
//----- client dll does not overwrite the vtable pointer after calling
//----- the ctor. And, since we expect the server dll to remain in
//----- memory indefinitely, there is no problem with vtables unexpectedly
//----- going away.
#define DLLIMPEXP
#endif



Thatís it, Thanks  Luis

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6934
  • AKA Daniel
Re: Deriving from AcDbPolyLine
« Reply #16 on: March 25, 2009, 01:38:35 AM »
I donít mind leaving my application loadedÖ in the end .. is this dangerous??  :laugh:

pkohut

  • Guest
Re: Deriving from AcDbPolyLine
« Reply #17 on: March 25, 2009, 01:56:42 AM »
I donít mind leaving my application loadedÖ in the end .. is this dangerous??  :laugh:

Nothing wrong with leaving it open and locked if that's what need to be done, but your
implementation has side effects. Your better to program the routine correctly.
#1 side effect is your object mutates on dwg filing from custom class to derived base class.
user would never know this is happening, but is this really a good thing?

Since you state you don't need a custom object but just wanted a special constructor, then
don't derived from AcDbEnity.  Make your own class that creates a new AcDbPolyilne
object and does any required work.  It's probably just as simple as what you've already
done and no side effects.

Paul

pkohut

  • Guest
Re: Deriving from AcDbPolyLine
« Reply #18 on: March 25, 2009, 02:23:44 AM »
I donít mind leaving my application loadedÖ in the end .. is this dangerous??  :laugh:

Let me add to that another way.  Scenario 1)  If the program went before a QA tester and
they filed a bug that said the application could not be unloaded you would then need to justify
the behavior or fix it.  In justifying the need to lock the application then the mutation side
effect is revealed.  QA tester would probably file a bug against that as well.

Scenario 2) Code is put up for code review with your peers and lead developer and they
were the ones to point out the mutation side effect and the application unload issue.
You would be asked to go back and fix it.  They might even be nice and give you a
quick lesson on design patterns and when to derive a new class on a base class, or just
create an instance of an object within a class and modify the objects properties.

Paul

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6934
  • AKA Daniel
Re: Deriving from AcDbPolyLine
« Reply #19 on: March 25, 2009, 03:30:29 AM »
Good points! Thanks Paul

Dan

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6934
  • AKA Daniel
Re: Deriving from AcDbPolyLine
« Reply #20 on: March 26, 2009, 09:04:25 PM »
FYI, you can declare the subclass with __declspec(novtable) and the ARX will unload properly, it seems to work very well.
However the use of this __declspec may cause problems if one needs to derive from the class again.
I decided just to make a wrapper with a conversion operator and see how that works.

Thatís one cool things about .NET, is that you can subclass any of the entity classes and in the end it still uses the underlying wrapper.

Chuck Gabriel

  • Guest
Re: Deriving from AcDbPolyLine
« Reply #21 on: March 27, 2009, 06:49:37 AM »
Isn't what you are doing the type of thing that protocol extensions are for?

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6934
  • AKA Daniel
Re: Deriving from AcDbPolyLine
« Reply #22 on: March 27, 2009, 09:38:15 AM »
Isn't what you are doing the type of thing that protocol extensions are for?

Thanks for the tip Chuck!

Iíve never heard about this before, Iíll need to study the docs on this.