TheSwamp

Code Red => .NET => Topic started by: Nightcrawler on January 21, 2021, 09:54:01 AM

Title: Getting extremely "large" negative block referece handles
Post by: Nightcrawler 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?
Title: Re: Getting extremely "large" negative block referece handles
Post by: dgorsman 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.
Title: Re: Getting extremely "large" negative block referece handles
Post by: huiz 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.
Title: Re: Getting extremely "large" negative block referece handles
Post by: Nightcrawler 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...
Title: Re: Getting extremely "large" negative block referece handles
Post by: gile 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).
Title: Re: Getting extremely "large" negative block referece handles
Post by: Nightcrawler 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.
Title: Re: Getting extremely "large" negative block referece handles
Post by: Nightcrawler 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?
Title: Re: Getting extremely "large" negative block referece handles
Post by: pera on April 22, 2021, 04:09:43 PM
Have look at this link (https://through-the-interface.typepad.com/through_the_interface/2007/02/getting_access_.html) to get handle from hex string.
Title: Re: Getting extremely "large" negative block referece handles
Post by: Nightcrawler 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.