Problem Deleting Last Object In The Database

Problem Deleting Last Object In The Database

Kyudos
Advisor Advisor
935 Views
6 Replies
Message 1 of 7

Problem Deleting Last Object In The Database

Kyudos
Advisor
Advisor

This one really has me stumped.

I have two custom objects derived from AcDbBlockReference. Lets call them A and B. I created B first, so A is the last item in the database. By design, if A is dropped on B (i.e., moved to the same position) A gets deleted. This causes AutoCAD 2018 (and 2017) to crash. However:

  • It only crashes if A is the last item in the database.
  • If I draw anything else the deletion is OK.
  • I can delete A manually without a problem in all cases.
  • AUDIT shows no (detectable) problems with the DWG.
  • As far as I can tell, there are no transactions left dangling.
  • The objects are appropriately opened for write.
  • The deletion goes through by DatabaseReactor::objectErased without issue.
  • If I skip the automatic object deletion....no crash.

Unfortunately, the call stack isn't much use - an Access Violation somewhere in acdb22.dll. It seems very likely the result of something I'm doing (or not doing) - but I don't know how to find out what.

 

Any ideas?

 

Thanks

0 Likes
Accepted solutions (1)
936 Views
6 Replies
Replies (6)
Message 2 of 7

tbrammer
Advisor
Advisor
  1. Can you provide a sample project that allows to reproduce this issue?
  2. You wrote: "If A is dropped on B ... A gets deleted". Is really A, the dropped object, deleted? So B acts like a trashcan. Or does A replace B and B gets deleted?
  3. When you write "A gets deleted": Do you mean A->erase() or really delete A ?
  4. How do you trigger the "delete" process when A is dropped to B?

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

0 Likes
Message 3 of 7

Kyudos
Advisor
Advisor

I doubt I can provide a sample without sending all my code 🙂 Might have to try though.

 

The deletion depends on the type of each object and other (complex!) conditions. In this case, the simplest I could make it, neither A nor B has any connections and A is simply deleted. In a more general case, the connections of A would be transferred to B, before A was removed.

 

When I say delete, yes I mean calling erase for the object.

 

When we move our objects, the 'drop' click triggers a search of that point for things we might need to connect to. Any objects at the dropped point are examined and appropriate connections are made, connections transferred and / or deletions are made.

 

0 Likes
Message 4 of 7

Kyudos
Advisor
Advisor

It's incredibly ugly, but I could avoid the crash by creating and then deleting a dummy object at the correct time, so that becomes the last in the database.

 

Is there an alternative function to acdbEntLast that will get me the last object id without selecting the last object?

 

 

EDIT: Actually I quickly tried this - I just get the crash when deleting the dummy object...

0 Likes
Message 5 of 7

Virupaksha_aithal
Autodesk Support
Autodesk Support

Hi,

 

Are you erasing the objects in a reactor callback or inside a command? if you are not erasing the objects inside a command, then please try erasing the objects inside a command.

 

 



Virupaksha Aithal KM
Developer Technical Services
Autodesk Developer Network

Message 6 of 7

tbrammer
Advisor
Advisor

Thanks @Virupaksha_aithal - this is actually what I tried to find out with my question "How do you trigger the "delete" process when A is dropped to B?". I agree that erasing it using a registered command is a good advice.

 

I recomment to register a command "MYDROPERASE" with the ACRX_CMD_NOHISTORY flag to avoid that this command shows up in the command history. Within the reactor you can call it using

acDocManager->sendStringToExecute(acDocManager->curDocument(), L"MYDROPERASE")

Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

0 Likes
Message 7 of 7

Kyudos
Advisor
Advisor
Accepted solution

I think this is the root of it. In the above example, A effectively deletes itself from within it's own subMoveGripPointsAt function. While this is all inside transactions, I guess it might still be somewhat risky? If I defer the deletion by making a "to be deleted" list which I run through later  - then it seems to be fine.

Obviously, up until now it seemed OK...except for the last object in the database thing. Not sure why that makes a difference - does deleting the last object truncate something perhaps?

0 Likes