Author Topic: PInvoke acdbEntUpd  (Read 16124 times)

0 Members and 1 Guest are viewing this topic.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: PInvoke acdbEntUpd
« Reply #15 on: June 12, 2010, 08:49:01 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)


ahhh .. makes sense  :-)
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 #16 on: June 12, 2010, 08:52:52 PM »
I started to use a home made PInvoke class (and for my own arx exported functions), and depending on the needs I add that on my new projects.
Sorry, I know I use that, but was easy for me to do the quick test here.


Thanks Luis

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

Did you have those DLLImport definitions in a  PInvoke class at one stage ??

LE3

  • Guest
Re: PInvoke acdbEntUpd
« Reply #17 on: June 12, 2010, 08:59:26 PM »
ahhh .. makes sense  :-)
And do not why this info is not on the latest arxref help (at least per my findings in the ARX sdk 2010)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: PInvoke acdbEntUpd
« Reply #18 on: June 12, 2010, 08:59:40 PM »
Thanks, I do the same thing .. API's in their own class.

thought is would be the case :-)
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.

pkohut

  • Guest
Re: PInvoke acdbEntUpd
« Reply #19 on: June 12, 2010, 09:23:57 PM »
if ObjectId in the .Net world == AcDbObjectId in the C++ world, then ads_name != ObjectId.

You have to use the .Net equivalent of these C++ API's
acdbGetObjectId(AcDbObjectId & objId, ads_name objName)  or
acdbGetAdsName(ads_name & objName, AcDbObjectId objId) to go the other way around.

Under the covers ads_name is 2 32 bit longs in 32 bit Autocad and 2 64 bit longs in 64 bit acad.
Up to 2007,
Code: [Select]
typedef long     ads_name[2];2008+,
Code: [Select]
#ifndef _WIN64
typedef __w64 long ads_name[2];
typedef __w64 long *ads_namep;
#else
typedef __int64 ads_name[2];
typedef __int64 *ads_namep;
#endif

(mental juggling here, about how TT's code would work)
But that really doesn't matter since the 128 bit ads_name of .Net will comfortably fit the 64 bit ads_name of 32 bit Acad, so they are compatible.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: PInvoke acdbEntUpd
« Reply #20 on: June 12, 2010, 09:26:25 PM »

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

I don't have a arxdef.chm ; assume you mean arxref.chm, which I was using

I'm using AC2011.
The ads_name is defined in adsdef.h as you say,
and described in the arxdev.chm ... which I hadn't looked at  :oops:

Thanks Luis.
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 #21 on: June 12, 2010, 09:31:58 PM »
if ObjectId in the .Net world == AcDbObjectId in the C++ world, then ads_name != ObjectId.

You have to use the .Net equivalent of these C++ API's
acdbGetObjectId(AcDbObjectId & objId, ads_name objName)  or
acdbGetAdsName(ads_name & objName, AcDbObjectId objId) to go the other way around.

< .. >

Thanks Paul
That clarifies jgr's comment and confirms the translation.

I really mucked up the array of longs for ads_name  :oops:

Thanks for posting.
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.

pkohut

  • Guest
Re: PInvoke acdbEntUpd
« Reply #22 on: June 12, 2010, 09:32:40 PM »
arxdev.chm ... which I hadn't looked at  :oops:

Type "ads_name" in arxdev.chm and check out "about" and "exchanging with AcDbObjectId's".

LE3

  • Guest
Re: PInvoke acdbEntUpd
« Reply #23 on: June 12, 2010, 09:40:13 PM »
Yikes... need another glasses :ugly: 
Yes, did not look into arxdev, normally I always use arxref...

I don't have a arxdef.chm ; assume you mean arxref.chm, which I was using

I'm using AC2011.
The ads_name is defined in adsdef.h as you say,
and described in the arxdev.chm ... which I hadn't looked at  :oops:

Thanks Luis.

LE3

  • Guest
Re: PInvoke acdbEntUpd
« Reply #24 on: June 12, 2010, 09:42:40 PM »
(mental juggling here, about how TT's code would work)

Which one?

Kerry

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


Thanks guys .. it's been an illuminating couple of hours  :-)
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 #26 on: June 13, 2010, 05:38:40 AM »

Quote from: Tony T adng
I think this is what you would use:

static extern int acdbEntUpd( out Int64 ename );

Something else to test :)
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 #27 on: June 13, 2010, 11:37:03 AM »
Did you tried Kerry?
Don't understand the out in there... the arx signature does not return the ads_name.... now I am confuse.
Now, I am going for my first coffee...


It works.

Another trick of Tony's bag of tricks... good


Quote from: Tony T adng
I think this is what you would use:

static extern int acdbEntUpd( out Int64 ename );

Something else to test :)

« Last Edit: June 13, 2010, 11:47:42 AM by LE3 »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: PInvoke acdbEntUpd
« Reply #28 on: June 13, 2010, 11:01:55 PM »

At the moment I'm quite happy with this test
... that may change , of course :)

Code: [Select]

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

namespace KdubTesting
{
    // CodeHimBelongaKdub Jun 2008
    public partial class TestCommands
    {
        const string ACAD_EXE = "Acad.exe";
        const short RTNORM = 5100;
        const short RTERROR = -5001;
        //===================================================================================
        // 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 ErrorStatus acdbGetAdsName(out long adsName, ObjectId id);
        /*
        * Parameters
        *  ads_name& objName    Output ads_name 
        *  AcDbObjectId objId   Input object ID 
        *
        * 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.
        */
        //===================================================================================
        // ARX signature:
        // int acdbEntUpd( const ads_name ent);
        [DllImport(ACAD_EXE, CallingConvention = CallingConvention.Cdecl,
            EntryPoint = "acdbEntUpd")]
        public static extern int acdbEntUpd(out long 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.
        */
        //===================================================================================
        [CommandMethod("Test0614a")]
        static public void Test0614a_acdbEntUpd_withInt64()
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            PromptEntityResult per = ed.GetEntity("\nSelect object: ");
            if(per.Status != PromptStatus.OK)
            {
                ed.WriteMessage("\n Nothing Selected");
                return;
            }

            ObjectId id = per.ObjectId;
            long adsName ;
            ErrorStatus es = acdbGetAdsName(out adsName, id);
            if(es != ErrorStatus.OK)
            {
                System.Windows.Forms.MessageBox.Show(
                    String.Format("ErrorStatus is: {0} \nCancelling Routine.", es),
                    "acdbGetAdsName ErrorStatus failure");
                return;
            }

            int api_Result = acdbEntUpd(out adsName);
            if(api_Result != RTNORM)
            {
                System.Windows.Forms.MessageBox.Show(
                   String.Format("ERRNO is : {0} \nCancelling Routine.",
                   AcadApp.GetSystemVariable("ERRNO")),
                   "acdbEntUpd api_Result failure");
                return;
            }
            //------------
            ed.WriteMessage("\n ObjectId is {0} ", id);
            ed.WriteMessage("\n adsName is {0} ", adsName);
            ed.WriteMessage("\n api acdbEntUpd_Result is {0} ", api_Result);
            ed.WriteMessage("\n System variable ERRNO  is {0} ",
                         AcadApp.GetSystemVariable("ERRNO"));
        }
    }
}
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 #29 on: June 13, 2010, 11:10:50 PM »

... however, something like this may be a little more practical.
I'd be happy to have someone seriously test it.
see file attached for includes.

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

namespace KdubTesting
{
    // CodeHimBelongaKdub Jun 2008
    public partial class TestCommands
    {
        const string ACAD_EXE = "Acad.exe";
        const short RTNORM = 5100;
        const short RTERROR = -5001;
        //===================================================================================
        // 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 ErrorStatus acdbGetAdsName(out long adsName, ObjectId id);
        /*
        * Parameters
        *  ads_name& objName    Output ads_name  
        *  AcDbObjectId objId   Input object ID  
        *
        * 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.
        */
        //===================================================================================
        // ARX signature:
        // int acdbEntUpd( const ads_name ent);
        [DllImport(ACAD_EXE, CallingConvention = CallingConvention.Cdecl,
            EntryPoint = "acdbEntUpd")]
        public static extern int acdbEntUpd(out long 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.
        */
        //===================================================================================
        //===================================================================================
        [CommandMethod("Test0614b")]
        static public void Test0614b_acdbEntUpd_withBoolTestMethod()
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            PromptEntityResult per = ed.GetEntity("\nSelect object: ");
            if(per.Status != PromptStatus.OK)
            {
                ed.WriteMessage("\n Nothing Selected");
                return;
            }
            ObjectId id = per.ObjectId;
            if( EntityUpdate(id))
                System.Windows.Forms.MessageBox.Show( "Entity Updates sucessfully", "Test0614b");
            else
                System.Windows.Forms.MessageBox.Show( "It hit the fan", "Test0614b");
        }
        //===================================================================================
        public static bool EntityUpdate(ObjectId id)
        {
            long adsName;
            if(acdbGetAdsName(out adsName, id) != ErrorStatus.OK)
                return false;
            return (acdbEntUpd(out adsName) == RTNORM);
        }
        //===================================================================================
     }
}

Quote
References
//AcCui :
//acdbmgd :
//acdbmgdbrep :
//AcDx :
//acmgd :
//AcMr :
//AcTcMgd :
//AcWindows :
//AdWindows :
//System :
//System.Core :
//System.Data :
//System.Windows.Forms :
//System.Xml&comref:
//Autodesk.AutoCAD.Interop
//Autodesk.AutoCAD.Interop.Common  
//stdole                        
//mscorlib

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.