Author Topic: Getting extremely "large" negative block referece handles  (Read 1895 times)

0 Members and 1 Guest are viewing this topic.

Nightcrawler

  • Mosquito
  • Posts: 7
Getting extremely "large" negative block referece handles
« on: January 21, 2021, 09:54:01 AM »
When I get handles for block references they usually look something like 153919. But for certain files I get handles that look like -4066801656873546453!
And when I try to get the block reference by that handle it throws an "eUnknownHandle" and crashes my AutoCAD instance.

Code: [Select]
long handle = -4066801656873546453;
Handle hn = new Handle(handle);
ObjectId blockId = sideDb.GetObjectId(false, hn, 0); // Crashes here!

It seems like a fairly uncommon issue as I've processed thousands of files without any problems. And even files in the same project works.

Anybody knows why this occurs, and what can I do to get the block reference when this occurs?

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Getting extremely "large" negative block referece handles
« Reply #1 on: January 21, 2021, 01:31:31 PM »
Where are these handles coming from - xdata?  Xrecords?

Rough guess, if from those there was some bad code modifying the wrong variable resulting into an unusable number or causing a numeric overflow from data type restrictions.  Either way there is no way of getting the actual handle value back.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

huiz

  • Swamp Rat
  • Posts: 913
  • Certified Prof C3D
Re: Getting extremely "large" negative block referece handles
« Reply #2 on: January 21, 2021, 03:21:45 PM »
Maybe you can fix it with the Audit command.


The large number looks like the minimum value of a long. It is negative and thus not valid. It might get fixed.
The conclusion is justified that the initialization of the development of critical subsystem optimizes the probability of success to the development of the technical behavior over a given period.

Nightcrawler

  • Mosquito
  • Posts: 7
Re: Getting extremely "large" negative block referece handles
« Reply #3 on: January 22, 2021, 02:46:58 AM »
@dgorsman I'm not sure what they are called tbh. I'm fairly inexperienced with the Autocad API, but this is how I get them:

Code: [Select]
using (var transaction = db.TransactionManager.StartTransaction())
{
    var layoutEntries = transaction.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;

    foreach (DBDictionaryEntry layoutEntry in layoutEntries)
    {
        var layout = transaction.GetObject(layoutEntry.Value, OpenMode.ForRead) as Autodesk.AutoCAD.DatabaseServices.Layout;
        var fileRecords = transaction.GetObject(layout.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;

        foreach (ObjectId id in fileRecords)
        {
            var blockRef = transaction.GetObject(id, OpenMode.ForRead) as BlockReference;
            var handle = blockRef.Handle.Value,
            var name = blockRef.Name,

            ...
        }
    }

    transaction.Abort();
}

@huiz, that's not a bad guess, but when I look at a couple of other handles I see values like -4066801656856679638, -4066801656856679152, -646675092. So not all are the same.
Running AUDIT on the model, as well as RECOVERALL I get this output "objects auditedAcDbBlockTableRecord: "A$C431C598E", XData Handle Unknown, Null" and then Autocad just hangs...

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Getting extremely "large" negative block referece handles
« Reply #4 on: January 22, 2021, 05:19:56 AM »
Hi,

Try replacing:
Code - C#: [Select]
  1. var blockRef = transaction.GetObject(id, OpenMode.ForRead) as BlockReference;
  2. var handle = blockRef.Handle.Value,
  3. var name = blockRef.Name,
with:
Code - C#: [Select]
  1. var blockRef = transaction.GetObject(id, OpenMode.ForRead) as BlockReference;
  2. if (blockRef != null)
  3. {
  4.     var handle = blockRef.Handle.Value;
  5.     var name = blockRef.Name;
  6.     // ...
  7. }
because layout's block table records contain entities which are not block references (at least one Viewport).
Speaking English as a French Frog

Nightcrawler

  • Mosquito
  • Posts: 7
Re: Getting extremely "large" negative block referece handles
« Reply #5 on: January 22, 2021, 06:00:44 AM »
Thanks @gile, but that's not the issue. I would have gotten null reference exceptions if that was the case. But it's always a good idea to check for nulls anyway.

On the BlockReference with weird handles I still get the other information that I need. So they still really are correct BlockReferences, just the handle is corrupted or something.

Nightcrawler

  • Mosquito
  • Posts: 7
Re: Getting extremely "large" negative block referece handles
« Reply #6 on: April 22, 2021, 07:54:30 AM »
I believe I have figured out part of the problem.

The reason I get a negative number is that the hex-value of the handle is larger than what fits in a regular long, which causes it to wrap to a negative number. It does fit in a ulong, but I don't think you can create a Handle from a ulong.

So this is still a problem since I can't create a new Handle from the negative number, since it's not the correct handle id.

Is it possible to create a Handle from a hex string or ulong instead of a long?

pera

  • Mosquito
  • Posts: 3
Re: Getting extremely "large" negative block referece handles
« Reply #7 on: April 22, 2021, 04:09:43 PM »
Have look at this link to get handle from hex string.

Nightcrawler

  • Mosquito
  • Posts: 7
Re: Getting extremely "large" negative block referece handles
« Reply #8 on: April 23, 2021, 02:25:38 AM »
Thanks, but that still causes the same phenomenon where the long wraps to negative.
Code: [Select]
long ln = Convert.ToInt64(pr.StringResult, 16);
Although! I did notice that the negative number was not the issue here. It seems to get the correct id even if the handle is negative.

My issue seems to be something else caused by
Code: [Select]
db.TryGetObjectId(new Handle(longHandle), out var id); where TryGetObjectId fails even on valid and existing object handles in specific situations.