Author Topic: PInvoke acdbEntUpd  (Read 16109 times)

0 Members and 1 Guest are viewing this topic.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
PInvoke acdbEntUpd
« on: June 12, 2010, 08:43:01 AM »
I'm brain dead and need a hand please.

I'm trying to achieve an Update on a Single entity.
The testbed is a little contrived, but you should get the idea ( I hope )
I've tried to code it to show the returns ...

Here's the issue :
After selecting an entity the acdbEntUpd() returns RTERROR (-5001 )
and an ERRNO of 5

My head hurts and I'm going to bed with the hope that the programming fairies solve this overnight  :-D


Comments are in-line

Code: [Select]
[assembly: CommandClass(typeof(KdubTesting.TestCommands))]

namespace KdubTesting
{
    // CodeHimBelongaKdub ©  Jun 2008
    public partial class Kdub_API
    {
        //====================================================================================
        [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
        public static extern int acdbEntUpd(Int64 adsName);
        //====================================================================================
        /*
          Acad::ErrorStatus acdbGetAdsName(
                ads_name& objName,
                AcDbObjectId obj
          );
          This function fills in objName with the ads_name that corresponds to the objId object ID.
          Returns Acad::eOk if successful. If objId is 0, then Acad::eNullObjectId is returned.
       */
        [DllImport("acdb18.dll", CallingConvention = CallingConvention.Cdecl,
        EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AAY01JVAcDbObjectId@@@Z")]
        public extern static ErrorStatus acdbGetAdsName(out Int64 objName, ObjectId objId );
        //====================================================================================

    }
    // CodeHimBelongaKdub ©  Jun 2008
    public partial class TestCommands
    {
        [CommandMethod("EntUpd")]
        static public void TestacdbEntUpd()
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
  
            PromptEntityResult res = ed.GetEntity("\nSelect an entity to Regen:");
            ObjectId id = res.ObjectId;
            Int64 adsName;
            ErrorStatus es;            

            using(Transaction tr = db.TransactionManager.StartTransaction())
            {
                es = Kdub_API.acdbGetAdsName(out adsName, id);

                ed.WriteMessage("\n adsName is {0} ", adsName);
                ed.WriteMessage("\n ErrorStatus is {0} ", es);

                int apiReturn = Kdub_API.acdbEntUpd(adsName);
                /*
                 * If acdbEntUpd() succeeds, it returns RTNORM  ( 5100 )
                 * otherwise,                it returns RTERROR.(-5001 )
                 * When acdbEntUpd() fails, it sets the system variable ERRNO
                 * to a value that indicates the reason for the failure.
                 */

                ed.WriteMessage("\n api acdbEntUpd_Return is {0} ", apiReturn);
                ed.WriteMessage("\n System variable ERRNO  is {0} ", AcadApp.GetSystemVariable("ERRNO"));

                /*
                 * Returns
                 * Command: EntUpd
                 *Select an entity to Regen:
                 *
                 * adsName is 8793785127955584200
                 * ErrorStatus is OK
                 * api acdbEntUpd_Return is -5001
                 * System variable ERRNO  is 5
                 */
                tr.Commit();
            }
        }
    }
}        
« Last Edit: June 12, 2010, 08:49:48 AM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Bryco

  • Water Moccasin
  • Posts: 1883
Re: PInvoke acdbEntUpd
« Reply #1 on: June 12, 2010, 10:56:13 AM »
You're going to hate this.
Change all from int64 to long
 adsName is 9179526903997960920
 ErrorStatus is OK
 api acdbEntUpd_Return is 4294962295
 System variable ERRNO  is 5

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: PInvoke acdbEntUpd
« Reply #2 on: June 12, 2010, 05:49:23 PM »

Thanks for looking Bryce.
I'll grab a coffee and start again. :)

kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: PInvoke acdbEntUpd
« Reply #3 on: June 12, 2010, 06:16:36 PM »
NoteThe possible values of ERRNO, and their meanings, are subject to change.
Online program error codes
 
Value
  Meaning
 
0
 No error
 
1
 Invalid symbol table name
 
2
 Invalid entity or selection set name
 
3
 Exceeded maximum number of selection sets
 
4
 Invalid selection set
 
5
 Improper use of block definition
6
 Improper use of xref
 
7
 Object selection: pick failed
 
8
 End of entity file
 
9
 End of block definition file
 
10
 Failed to find last entity
 
//=======================================


kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: PInvoke acdbEntUpd
« Reply #4 on: June 12, 2010, 06:46:42 PM »
Bryce,
a long and an Int64 are the same thing  64bit signed integer
'long' is just an alias for Int64.

In fact, if we right-click on 'long' and select 'GoToDefinition' the definitionsig' is
    // Summary:
    //     Represents a 64-bit signed integer.
    [Serializable]
    [ComVisible(true)]
    public struct Int64 : IComparable, IFormattable, IConvertible, IComparable<long>, IEquatable<long>
    { //................


//--------------------------------------------------

another clue :
The acdbEntUpd generates an ERRNO of 5
When the routine returns to AutoCAD, the ERRNO command from the commandLine reports 2.



Quote
Command: errno
Enter new value for ERRNO <0>:

Command: entupd

Select an entity to Regen:
 adsName is 9158139860942894088
 ErrorStatus is OK
 api acdbEntUpd_Return is -5001
 System variable ERRNO  is 5
 Complete: System variable ERRNO  is 5

Command: errno
Enter new value for ERRNO <2>:
« Last Edit: June 12, 2010, 06:54:46 PM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: PInvoke acdbEntUpd
« Reply #5 on: June 12, 2010, 07:12:19 PM »

The 'Scrambled' name for acdbGetAdsName is the same in acdb17.dll 32bit  and acdb18.dll 32bit ... so my DllImports should be suitable for AC 2007-AC2011 ( once I get the bug sorted. )
« Last Edit: June 12, 2010, 07:16:58 PM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

jgr

  • Guest
Re: PInvoke acdbEntUpd
« Reply #6 on: June 12, 2010, 07:30:27 PM »
Sorry, i don't undertand, but try:
acdbEntUpd(ObjectId adsName)

I think  adsname = objectid

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: PInvoke acdbEntUpd
« Reply #7 on: June 12, 2010, 07:52:02 PM »
Thanks for looking

Perhaps it should.
I tried that first and got the same error, so tried the acdbGetAdsName()

ie : using
        [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
        //public static extern int acdbEntUpd(long adsName);
        public static extern int acdbEntUpd(ObjectId objId);

and
int apiReturn = Kdub_API.acdbEntUpd(id);

I get
Command: entupd

Select an entity to Regen:
 api acdbEntUpd_Return is -5001
 System variable ERRNO  is 5
 Complete: System variable ERRNO  is 5
[added]
BUT errno at the commandLine is 0 now as it should be :)
« Last Edit: June 12, 2010, 08:05:48 PM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

LE3

  • Guest
Re: PInvoke acdbEntUpd
« Reply #8 on: June 12, 2010, 07:54:21 PM »
See if this works (learned from the masters).

Code: [Select]
       // ARX signature:
        // int acdbEntUpd( const ads_name ent);
        [DllImport(ACAD_EXE, CallingConvention = CallingConvention.Cdecl, EntryPoint = "acdbEntUpd")]
        public static extern int acdbEntUpd ( long[] ent );

        // ARX signature:
        // Acad::ErrorStatus acdbGetAdsName(ads_name& objName, AcDbObjectId objId);
        [DllImport("acdb18.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AAY01JVAcDbObjectId@@@Z")]
        public static extern int acdbGetAdsName ( long[] objName, ObjectId objId );

        [CommandMethod("TEST1")]
        static public void CmdTest ( )
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            PromptEntityResult per = ed.GetEntity("\nSelect object: ");
            if (per.Status != PromptStatus.OK) return;
            long[] objName = new long[] { 0, 0 };
            PInvoke.acdbGetAdsName(objName, per.ObjectId);
            PInvoke.acdbEntUpd(objName);
        }

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: PInvoke acdbEntUpd
« Reply #9 on: June 12, 2010, 08:08:53 PM »

Thanks Luis, I'll have a look shortly

Do you know why an array of longs is used as a parameter ??
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: PInvoke acdbEntUpd
« Reply #10 on: June 12, 2010, 08:11:08 PM »

I take it from the use of ACAD_EXE that the code is from Tony .. I've noticed that he uses a constant of that name to represent "acad.exe"
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

LE3

  • Guest
Re: PInvoke acdbEntUpd
« Reply #11 on: June 12, 2010, 08:30:41 PM »

Thanks Luis, I'll have a look shortly

Do you know why an array of longs is used as a parameter ??


because of this:
typedef long ads_name[2];  (under arxdef.chm a2008 and adsdef.h)

LE3

  • Guest
Re: PInvoke acdbEntUpd
« Reply #12 on: June 12, 2010, 08:31:19 PM »

I take it from the use of ACAD_EXE that the code is from Tony .. I've noticed that he uses a constant of that name to represent "acad.exe"
yep, learned that style from him :)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: PInvoke acdbEntUpd
« Reply #13 on: June 12, 2010, 08:44:04 PM »
Thanks Luis

One more:
Why are you using PInvoke.xxxxx ??

Did you have those DLLImport definitions in a  PInvoke class at one stage ??
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: PInvoke acdbEntUpd
« Reply #14 on: June 12, 2010, 08:47:28 PM »
Seems to work fine .. need to do a bit more testing ..

the call to acdbEntUpd returns  5100 (ie RTNORM ) which is good :)

Thanks.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.