Author Topic: Entrypoint variable to AutoCAD release  (Read 4361 times)

0 Members and 1 Guest are viewing this topic.

Fred Tomke

  • Newt
  • Posts: 38
  • [ Mr. Bad Guy ]
Entrypoint variable to AutoCAD release
« on: April 13, 2011, 08:16:51 AM »
Hello,

in AutoCAD 2012 the key for PostCommand has changed I wanted to solve this not by subclass the function but to create a static property to assign the key.

Code: [Select]
   private static string PostCommandEntryPoint
    {
      get
      {
        if (Product.AcadRel < 18.2)
          return "?acedPostCommand@@YAHPB_W@Z";
        else
          return "?acedPostCommand@@YAHPEB_W@Z";
      }
    }

    [System.Security.SuppressUnmanagedCodeSecurity]
    [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = PostCommandEntryPoint)]
    private static extern int acedPostCommand(string strExpr);


Unfortunately, MSVS notes that "EntryPoint =" needs a constant or typeof or array creation expression. Is there another chance to make it variable?

Thanks Fred
Fred Tomke
Dipl.-Ing. (FH) Landespflege

[ landscaper - landscape developer - digital landscape and urban design]

LE3

  • Guest
Re: Entrypoint variable to AutoCAD release
« Reply #1 on: April 13, 2011, 03:34:07 PM »
What I have been done is to add a conditional compilation symbol.
Go to Properties - Build - Conditional compilation symbols: _ACADTARGET_18

Then, I simple use:
#if (_ACADTARGET_18)
// your PInvoke calls goes here...
        // target A2010
#endif
#if (_ACADTARGET_17)
        // target A2007 trough A2009
#endif
#if (_ACADTARGET_18x64)
        // target A2009
#endif
#if (_ACADTARGET_17x64)
        // target A2009
#endif

kaefer

  • Guest
Re: Entrypoint variable to AutoCAD release
« Reply #2 on: April 13, 2011, 03:57:35 PM »
What I have been done is to add a conditional compilation symbol.

Very well, that makes it variable at compile time. But what's wrong with listing the alternatives as static methods? They're private anyway.
Code: [Select]
    public class Class1
    {
        private static void PostCommand(string strExpr)
        {
            if (Product.AcadRel < 18.2)
                acedPostCommandPre182(strExpr);
            else
                acedPostCommand182(strExpr);
        }

        [System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode,
            EntryPoint = "?acedPostCommand@@YAHPB_W@Z")]
        private static extern int acedPostCommandPre182(string strExpr);

        [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode,
            EntryPoint = "?acedPostCommand@@YAHPEB_W@Z")]
        private static extern int acedPostCommand182(string strExpr);
    }

in AutoCAD 2012 the key for PostCommand has changed I wanted to solve this not by subclass the function but to create a static property to assign the key.

For subclassing see sinc's example here


Fred Tomke

  • Newt
  • Posts: 38
  • [ Mr. Bad Guy ]
Re: Entrypoint variable to AutoCAD release
« Reply #3 on: April 14, 2011, 02:32:21 AM »
For subclassing see sinc's example here

Thanks a lot, but I knew the way of subclassing. Since I was told that the entrypoints of 64Bit and 32Bit releases may differ I created two different classes with the same methods. But exactly that I wanted to avoid (sorry for my bad English). I hoped that the name of the entrypoint could be variable to shorten the code.

Thank you.
Fred

Code: [Select]
    private class Acadx86
    {
      [System.Security.SuppressUnmanagedCodeSecurity]
      [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = "?acedPostCommand@@YAHPB_W@Z")]
      private static extern int acedPostCommand(string strExpr);

      public static int PostCommand(string strExpr)
      {
        return acedPostCommand(strExpr);
      }
    [...other...]
    }

    private class Acadx64
    {
      [System.Security.SuppressUnmanagedCodeSecurity]
      [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = "?acedPostCommand@@YAHPEB_W@Z")]
      private static extern int acedPostCommand(string strExpr);

      public static int PostCommand(string strExpr)
      {
        return acedPostCommand(strExpr);
      }
    [...other...]
    }

    public static int PostCmd(string strCmd)
    {
      return (Common.OS.Is64Bit) ? Acadx64.PostCommand(strCmd) : Acadx86.PostCommand(strCmd);
    }
Fred Tomke
Dipl.-Ing. (FH) Landespflege

[ landscaper - landscape developer - digital landscape and urban design]

LE3

  • Guest
Re: Entrypoint variable to AutoCAD release
« Reply #4 on: April 14, 2011, 11:01:43 AM »
Very well, that makes it variable at compile time. But what's wrong with listing the alternatives as static methods? They're private anyway.

Don't see a problem. :)

Fred Tomke

  • Newt
  • Posts: 38
  • [ Mr. Bad Guy ]
Re: Entrypoint variable to AutoCAD release
« Reply #5 on: April 15, 2011, 01:54:42 AM »
What I have been done is to add a conditional compilation symbol.
Go to Properties - Build - Conditional compilation symbols: _ACADTARGET_18

Hi, does it mean, that you compile a dll for each AutoCAD release and plattform?
I still manged it to have only one for all.

Fred
Fred Tomke
Dipl.-Ing. (FH) Landespflege

[ landscaper - landscape developer - digital landscape and urban design]

Fred Tomke

  • Newt
  • Posts: 38
  • [ Mr. Bad Guy ]
Re: Entrypoint variable to AutoCAD release
« Reply #6 on: April 15, 2011, 01:56:29 AM »
[...] But what's wrong with listing the alternatives as static methods? They're private anyway.

Yes, you are right. I slept over it again and I've changed it this way.

Thanks, Fred
Fred Tomke
Dipl.-Ing. (FH) Landespflege

[ landscaper - landscape developer - digital landscape and urban design]

LE3

  • Guest
Re: Entrypoint variable to AutoCAD release
« Reply #7 on: April 15, 2011, 10:34:58 AM »
Hi, does it mean, that you compile a dll for each AutoCAD release and plattform?
I still manged it to have only one for all.
In my case, many of the solutions are custom objects (ARX) and required to be like this, with the exception of the last two that still are custom objects but done via NET wrappers, to avoid the use of PInvoke :)
« Last Edit: April 15, 2011, 10:38:42 AM by LE »