Author Topic: Getting and Putting Lisp Variables from .NET  (Read 24843 times)

0 Members and 1 Guest are viewing this topic.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Getting and Putting Lisp Variables from .NET
« on: November 14, 2010, 01:31:35 AM »
I've seen this question a few times so I had a little play this afternoon.

Attached is the solution and a lisp file to set the initial values.

Here's the output.

Quote
Command: appload
LispData.LSP successfully loaded.

Command: doit1114a

Res1 : ((5005,Apple))
Res2 : ((5001,1))
Res3 : ((5009,(1,1,1)))
Res4 :
((5016,-1)(5016,-1)(5005,A)(5003,1)(5018,-1)(5016,-1)(5005,B)(5001,2)(5018,-1)(5
016,-1)(5005,C)(5005,Charlie)(5018,-1)(5017,-1))
******
5016 -> -1
5016 -> -1
5005 -> A
5003 -> 1
5018 -> -1
5016 -> -1
5005 -> B
5001 -> 2
5018 -> -1
5016 -> -1
5005 -> C
5005 -> Charlie
5018 -> -1
5017 -> -1
******
Command: DOIT1114b

Name of lisp-variable: varxx

Res1 : ((5005,This is the transported Text))
Command: DOIT1114c

Name of lisp-variable: var1114c

Input String Value: JoeBloggs

Input Integer Value: 42

Input or select Angle:  Specify second point:
Input or Select 3DPoint:
******
5016 -> -1
5005 -> JoeBloggs
5003 -> 42
5001 -> 0.436330845007164
5009 -> (35.3589744333294,194.722414563616,0)
5017 -> -1
******
Command: !var1114c
("JoeBloggs" 42 0.436330845007164 (35.359 194.722 0.0))


The initial Lisp values
Code - Auto/Visual Lisp: [Select]
  1. ;;Test Data for DoIt1114 .Net test
  2. (setq TestVar1 "Apple")
  3. (setq TestVar2 1.0)
  4. (setq TestVar3 (list 1.0 1.0 1.0))
  5. (setq TestVar4 (list (cons "A" 1) (cons "B" 2.0) (cons "C" "Charlie")))
  6.  
  7. (vl-cmdf "_NetLoad" "GetAndSetLispSymbol.DLL")
  8.  
  9.  
  10. ;; (findfile "GetAndSetLispSymbol.DLL")
  11. ;; (findfile "LispData.lsp")
  12. ;; "C:\\Users\\kdub\\documents\\visual studio 2010\\Projects\\CAD\\GetAndSetLispSymbol\\bin\\Debug\\LispData.lsp"
  13.  

The C# code
Code - C#: [Select]
  1. // CodeHimBelonga kdub@theSwamp
  2. //
  3. #region UsingRegion
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Data;
  8. using System.IO;
  9. using System.Text;
  10. using System.Text.RegularExpressions;
  11. using System.Runtime.InteropServices;
  12.  
  13. using Autodesk.AutoCAD.ApplicationServices;
  14. using Autodesk.AutoCAD.DatabaseServices;
  15. using Autodesk.AutoCAD.EditorInput;
  16. using Autodesk.AutoCAD.Geometry;
  17. using Autodesk.AutoCAD.Runtime;
  18. using Autodesk.AutoCAD.Windows;
  19.  
  20. using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
  21. using ACAD = Autodesk.AutoCAD.Interop;
  22. using ACADCOM = Autodesk.AutoCAD.Interop.Common;
  23.  
  24. #endregion
  25.  
  26. [assembly: CommandClass(typeof(kdub_Testing.MyCommandsClass))]
  27.  
  28. namespace kdub_Testing
  29. {
  30.     public class MyCommandsClass
  31.     {
  32.         Document dwg;
  33.         Database db;
  34.         Editor ed;
  35.         //
  36.         public MyCommandsClass()
  37.         {
  38.             ActiveDrawing = AcadApp.DocumentManager.MdiActiveDocument;
  39.         }
  40.         Document ActiveDrawing
  41.         {
  42.             get { return dwg; }
  43.             set
  44.             {
  45.                 dwg = value;
  46.                 if(dwg != null) {
  47.                     db = dwg.Database;
  48.                     ed = dwg.Editor;
  49.                 } else { db = null; ed = null; }
  50.             }
  51.         }
  52.         //
  53.         // Type of resbuf element
  54.         // credit to Alexander Rivilis
  55.         const short RTNONE = 5000;      /* No result                            */
  56.         const short RTREAL = 5001;      /* Real number                          */
  57.         const short RTPOshort = 5002;   /* 2D poshort X and Y only              */
  58.         const short RTSHORT = 5003;     /* Short integer                        */
  59.         const short RTANG = 5004;       /* Angle                                */
  60.         const short RTSTR = 5005;       /* String                               */
  61.         const short RTENAME = 5006;     /* Entity name                          */
  62.         const short RTPICKS = 5007;     /* Pick set                             */
  63.         const short RTORshort = 5008;   /* Orientation                          */
  64.         const short RT3DPOshort = 5009; /* 3D poshort - X, Y, and Z             */
  65.         const short RTLONG = 5010;      /* Long integer                         */
  66.         const short RTVOID = 5014;      /* Blank symbol                         */
  67.         const short RTLB = 5016;        /* list begin                           */
  68.         const short RTLE = 5017;        /* list end                             */
  69.         const short RTDOTE = 5018;      /* dotted pair                          */
  70.         const short RTNIL = 5019;       /* nil                                  */
  71.         const short RTDXF0 = 5020;      /* DXF code 0 for ads_buildlist only    */
  72.         const short RTT = 5021;         /* T atom                               */
  73.         const short RTRESBUF = 5023;    /* resbuf                               */
  74.         const short RTMODELESS = 5027;  /* interrupted by modeless dialog       */
  75.         //
  76.         // Error return code
  77.         const short RTNORM = 5100;      /* Request succeeded                    */
  78.         const short RTERROR = -5001;    /* Some other error                     */
  79.         const short RTCAN = -5002;      /* User cancelled request -- Ctl-C      */
  80.         const short RTREJ = -5003;      /* AutoCAD rejected request -- invalid  */
  81.         const short RTFAIL = -5004;     /* Link failure -- Lisp probably died   */
  82.         const short RTKWORD = -5005;    /* Keyword returned from getxxx() routine   */
  83.         const short RTINPUTTRUNCATED = -5008; /* Input didn't all fit in the buffer */
  84.  
  85.         ///
  86.  
  87.         [System.Security.SuppressUnmanagedCodeSecurity]
  88.         [DllImport("acad.exe",
  89.             EntryPoint = "acedPutSym",
  90.             CharSet = CharSet.Unicode,
  91.             CallingConvention = CallingConvention.Cdecl)
  92.         ]
  93.         extern static private int acedPutSym(string args, IntPtr result);
  94.  
  95.         [System.Security.SuppressUnmanagedCodeSecurity]
  96.         [DllImport("acad.exe",
  97.             EntryPoint = "acedGetSym",
  98.             CharSet = CharSet.Unicode,
  99.             CallingConvention = CallingConvention.Cdecl)
  100.         ]
  101.         extern static private int acedGetSym(string args, out IntPtr result);
  102.  
  103.         /// <summary>
  104.         ///
  105.         /// </summary>
  106.         /// <param name="name"></param>
  107.         /// <returns>ResultBuffer</returns>
  108.         internal static ResultBuffer GetLispSym(string name)
  109.         {
  110.             IntPtr ip = IntPtr.Zero;
  111.             if((acedGetSym(name, out ip) == RTNORM) && (ip != IntPtr.Zero)) {
  112.                 return ResultBuffer.Create(ip, true);
  113.             }
  114.             return null;
  115.         }
  116.  
  117.         /// <summary>
  118.         ///
  119.         /// </summary>
  120.         [CommandMethod("DoIt1114a", CommandFlags.Modal)]
  121.         public void DoIt1114a()
  122.         {
  123.             ResultBuffer res1 = GetLispSym("TestVar1");
  124.  
  125.             ResultBuffer res2 = GetLispSym("TestVar2");
  126.  
  127.             ResultBuffer res3 = GetLispSym("TestVar3");
  128.  
  129.             ResultBuffer res4 = GetLispSym("TestVar4");
  130.  
  131.             ed.WriteMessage("{0} : {1}", "\nRes1", res1.ToString());
  132.             ed.WriteMessage("{0} : {1}", "\nRes2", res2.ToString());
  133.             ed.WriteMessage("{0} : {1}", "\nRes3", res3.ToString());
  134.             ed.WriteMessage("{0} : {1}", "\nRes4", res4.ToString());
  135.  
  136.             if(res4 != null) {
  137.                 // credit to Alexander Rivilis
  138.                 StringBuilder s = new StringBuilder();
  139.                 s.Append("\n******");
  140.                 foreach(TypedValue val in (System.Collections.IEnumerable)res4) {
  141.                     s.AppendFormat("\n{0} -> {1}", val.TypeCode, val.Value.ToString());
  142.                 }
  143.                 s.Append("\n******");
  144.                 ed.WriteMessage(s.ToString());
  145.             }
  146.  
  147.         }
  148.         /// <summary>
  149.         ///
  150.         /// </summary>
  151.         [CommandMethod("DoIt1114b", CommandFlags.Modal)]
  152.         public void DoIt1114b()
  153.         {
  154.             PromptResult res = ed.GetString("\nName of lisp-variable: ");
  155.             string LispVarName = string.Empty;
  156.             if(res.Status == PromptStatus.OK) {
  157.                 ResultBuffer rb = new ResultBuffer();
  158.                 LispVarName = res.StringResult;
  159.                 rb.Add(new TypedValue(RTSTR, "This is the transported Text"));
  160.                 //
  161.                 acedPutSym(LispVarName, rb.UnmanagedObject);
  162.             }
  163.             ed.WriteMessage("{0} : {1}", "\nRes1", GetLispSym(LispVarName).ToString());
  164.         }
  165.         /// <summary>
  166.         ///
  167.         /// </summary>
  168.         [CommandMethod("DoIt1114c", CommandFlags.Modal)]
  169.         public void DoIt1114c()
  170.         {
  171.             /*
  172.              *  Lets say we have an expectation that a Lisp List has a specific structure
  173.              *  of (list String Integer RotationAngle 3dPoint)
  174.              *  
  175.              *  we need to build the ResultBuffer to suit.          
  176.              */
  177.             PromptResult resName = ed.GetString("\nName of lisp-variable: ");
  178.             string LispVarName = resName.StringResult;
  179.  
  180.             PromptResult resStr = ed.GetString("\nInput String Value : ");
  181.             PromptIntegerResult resInt = ed.GetInteger("\nInput Integer Value : ");
  182.             PromptDoubleResult resAng = ed.GetAngle("\nInput or select Angle : ");
  183.             PromptPointResult resPt = ed.GetPoint("\nInput or Select 3DPoint : ");
  184.  
  185.             // For the exercise, assume the values are Valid .... 'danger Will Robinson'
  186.             //
  187.             // Use Tony's TypedValueList class to build the result buffer.
  188.             TypedValueList dataList = new TypedValueList();
  189.  
  190.             dataList.Add(LispDataType.ListBegin, 0);
  191.  
  192.             dataList.Add(LispDataType.Text, resStr.StringResult);
  193.  
  194.             dataList.Add(LispDataType.Int32, resInt.Value);
  195.  
  196.             dataList.Add(LispDataType.Angle, resAng.Value);
  197.  
  198.             dataList.Add(LispDataType.Point3d, resPt.Value);
  199.  
  200.             dataList.Add(LispDataType.ListEnd, 0);
  201.  
  202.             // add the Variable to AutoCad
  203.             acedPutSym(LispVarName, ((ResultBuffer)dataList).UnmanagedObject);
  204.  
  205.             // get the Lisp variable from AutoCAD
  206.             ResultBuffer rb1114c = GetLispSym(LispVarName);
  207.  
  208.             if(rb1114c != null) {
  209.                 // credit to Alexander Rivilis
  210.                 StringBuilder s = new StringBuilder();
  211.                 s.Append("\n******");
  212.                 foreach(TypedValue val in (System.Collections.IEnumerable)rb1114c) {
  213.                     s.AppendFormat("\n{0} -> {1}", val.TypeCode, val.Value.ToString());
  214.                 }
  215.                 s.Append("\n******");
  216.                 ed.WriteMessage(s.ToString());
  217.             }
  218.         }
  219.     }
  220. }
  221.  
  222.  

and Tony's TypedValueList class to build the result buffer in the last example.
Code - C#: [Select]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using Autodesk.AutoCAD.Runtime;
  8.  
  9. namespace kdub_Testing
  10. {
  11.     public class TypedValueList :List<TypedValue>
  12.     {
  13.         // With thanks to Tony Tanzillo
  14.         // http://www.theswamp.org/index.php?topic=14495.msg186823#msg186823
  15.         //
  16.         public TypedValueList(params TypedValue[] args)
  17.         {
  18.             AddRange(args);
  19.         }
  20.  
  21.         // Make it a bit easier to add items:
  22.  
  23.         public void Add(int typecode, object value)
  24.         {
  25.             base.Add(new TypedValue(typecode, value));
  26.         }
  27.         public void Add(LispDataType type, object value)
  28.         {
  29.             Add(new TypedValue((int)type, value));
  30.         }
  31.         public void Add(DxfCode code, object value)
  32.         {
  33.             Add(new TypedValue((int)code, value));
  34.         }
  35.  
  36.         // Implicit conversion to SelectionFilter
  37.         public static implicit operator SelectionFilter(TypedValueList src)
  38.         {
  39.             return src != null ? new SelectionFilter(src) : null;
  40.         }
  41.  
  42.         // Implicit conversion to ResultBuffer
  43.         public static implicit operator ResultBuffer(TypedValueList src)
  44.         {
  45.             return src != null ? new ResultBuffer(src) : null;
  46.         }
  47.  
  48.         // Implicit conversion to TypedValue[]
  49.         public static implicit operator TypedValue[](TypedValueList src)
  50.         {
  51.             return src != null ? src.ToArray() : null;
  52.         }
  53.  
  54.         // Implicit conversion from TypedValue[]
  55.         public static implicit operator TypedValueList(TypedValue[] src)
  56.         {
  57.             return src != null ? new TypedValueList(src) : null;
  58.         }
  59.  
  60.         // Implicit conversion from SelectionFilter
  61.         public static implicit operator TypedValueList(SelectionFilter src)
  62.         {
  63.             return src != null ? new TypedValueList(src.GetFilter()) : null;
  64.         }
  65.  
  66.         // Implicit conversion from ResultBuffer
  67.         public static implicit operator TypedValueList(ResultBuffer src)
  68.         {
  69.             return src != null ? new TypedValueList(src.AsArray()) : null;
  70.         }
  71.     }
  72. }
  73.  

The solution attachment
« Last Edit: January 21, 2012, 04:32:54 PM by Kerry »
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.

Ketxu

  • Newt
  • Posts: 109
Re: Getting and Putting Lisp Variables from .NET
« Reply #1 on: December 13, 2011, 08:54:16 AM »
This requires atleast Net 3.5 ? and with acWindows,  can i use it for CAD2008 ? (i can't find path to reference this file)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Getting and Putting Lisp Variables from .NET
« Reply #2 on: January 20, 2012, 05:55:41 PM »
Missed your questions ... perhaps they are resolved by now.

This requires atleast Net 3.5 ? and with acWindows,

I think 3.0 will work.

can i use it for CAD2008 ?

I don't have acad2008 ... have you tried it ?

(i can't find path to reference this file)

Which file are you trying to reference ?

Regards
kdub

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.

FELIX

  • Bull Frog
  • Posts: 241
Re: Getting and Putting Lisp Variables from .NET
« Reply #3 on: January 21, 2012, 04:40:54 PM »
Thanks, I converted to VB.NET.
 I need one more help, I am not expert in VB.NET, use only for display screens for Autolisp because the DCL is very rigid.

Where do I put the conversion of VB.NET in a CLASS? in a MODULE? Where?

I just need the functions GETLISPSYM and SETLISPSYM to put in a MODULE in VB.NET

 Can you help?
OK.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Getting and Putting Lisp Variables from .NET
« Reply #4 on: January 21, 2012, 05:03:23 PM »
Thanks, I converted to VB.NET.
 I need one more help, I am not expert in VB.NET, use only for display screens for Autolisp because the DCL is very rigid.

< .. >

If that is the case you may be better served using OpenDCL for your dialogs.
http://www.opendcl.com/forum/
http://www.opendcl.com/download/

.. and learn the fundamentals of .NET in your spare time.
http://usa.autodesk.com/adsk/servlet/index?siteID=123112&id=18162797

« Last Edit: January 21, 2012, 05:14:43 PM by Kerry »
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.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Getting and Putting Lisp Variables from .NET
« Reply #5 on: January 21, 2012, 05:19:18 PM »
Kerry, nice thread.

I'd add to the TypedValueList three more Add() methods with a single argument (int, LispDataType and DxfCode) as there's a TypedValue constructor which accepts only one  argument.
Speaking English as a French Frog

FELIX

  • Bull Frog
  • Posts: 241
Re: Getting and Putting Lisp Variables from .NET
« Reply #6 on: January 21, 2012, 06:41:35 PM »
Kerry, very good topic of Autodesk, I read in my spare time.

I am limited to (slowly) to learn modern languages​​, I have learned many liguagens programming in the last 40 years (COBOL, FORTRAN, PASCAL, PL I, CLIPPER, AutoLISP, VB6 and VB.NET now) I am the time of the punch card.

Only Autolisp more than 25 years and utilizes a file or the User variables for transferring values ​​from AutoCAD's AutoLISP for VB.NET.

 If you can help me, fine, if not already paid by the topic of Autodesk.

 OK.
OK.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Getting and Putting Lisp Variables from .NET
« Reply #7 on: January 22, 2012, 07:05:35 AM »
Hi,

I tried to simplify a little what Kerry posted.
I don't use Tony's TypedValueList class which is not, in my opinion, so interesting in this case.
It's possible to avoid using Alexander's const values as most of them can be found in LispDataType and PromptStatus enums and this way allows a more readable code.
Code: [Select]
LispDataType
None           5000
Double         5001
Point2d        5002
Int16          5003
Angle          5004
Text           5005
ObjectId       5006
SelectionSet   5007
Orientation    5008
Point3d        5009
Int32          5010
Void           5014
ListBegin      5016
ListEnd        5017
DottedPair     5018
Nil            5019
T_atom         5021

PromptStatus
None           5000
Modeless       5027
Other          5028
OK             5100
Keyword        -5005
Cancel         -5002
Error          -5001

The LispExtension class provides three static (Shared) methods : InvokeLisp(), GetLispSym() and SetLispSym().

Code - C#: [Select]
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5.  
  6. namespace AcadExtensions
  7. {
  8.     // Credits to Tony Tanzillo, Alexander Rivillis, Kerry Brown...
  9.  
  10.     /// <summary>
  11.     /// Provides methods to comunicate with AutoLISP.
  12.     /// </summary>
  13.     public class LispExtensions
  14.     {
  15.         [System.Security.SuppressUnmanagedCodeSecurity]
  16.         [DllImport("acad.exe", EntryPoint = "acedInvoke",
  17.             CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
  18.         extern static private int acedInvoke(IntPtr args, out IntPtr result);
  19.  
  20.         /// <summary>
  21.         /// Invoke a LISP function.
  22.         /// The LISP function must be defined as an external subroutine using the c: prefix or invoking vl-acad-defun.
  23.         /// This is no more mandatory since A2011 as the managed Application.Invoke() method wraps acedInvoke.
  24.         /// </summary>
  25.         /// <param name="args">The function name (string) following by the function arguments.</param>
  26.         /// <returns>The LISP function return value or null if failed.</returns>
  27.         public static ResultBuffer InvokeLisp(ResultBuffer args)
  28.         {
  29.             IntPtr ip = IntPtr.Zero;
  30.             int status = acedInvoke(args.UnmanagedObject, out ip);
  31.             if (status == (int)PromptStatus.OK && ip != IntPtr.Zero)
  32.                 return ResultBuffer.Create(ip, true);
  33.             return null;
  34.         }
  35.  
  36.         [System.Security.SuppressUnmanagedCodeSecurity]
  37.         [DllImport("acad.exe", EntryPoint = "acedPutSym",
  38.             CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
  39.         extern static private int acedPutSym(string args, IntPtr result);
  40.  
  41.         /// <summary>
  42.         /// Set a LISP variable value.
  43.         /// </summary>
  44.         /// <param name="name">The variable name.</param>
  45.         /// <param name="rb">The variable value</param>
  46.         public static void SetLispSym(string name, ResultBuffer rb)
  47.         {
  48.             acedPutSym(name, rb.UnmanagedObject);
  49.         }
  50.  
  51.         [System.Security.SuppressUnmanagedCodeSecurity]
  52.         [DllImport("acad.exe", EntryPoint = "acedGetSym",
  53.             CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
  54.         extern static private int acedGetSym(string args, out IntPtr result);
  55.  
  56.         /// <summary>
  57.         /// Get a LISP variable value.
  58.         /// </summary>
  59.         /// <param name="name">The variable name.</param>
  60.         /// <returns>The variable value or null if failed.</returns>
  61.         public static ResultBuffer GetLispSym(string name)
  62.         {
  63.             IntPtr ip = IntPtr.Zero;
  64.             int status = acedGetSym(name, out ip);
  65.             if (status == (int)PromptStatus.OK && ip != IntPtr.Zero)
  66.             {
  67.                 return ResultBuffer.Create(ip, true);
  68.             }
  69.             return null;
  70.         }
  71.     }
  72. }
  73.  

Code - vb.net: [Select]
  1. Imports System.Runtime.InteropServices
  2. Imports Autodesk.AutoCAD.DatabaseServices
  3. Imports Autodesk.AutoCAD.EditorInput
  4.  
  5. Namespace AcadExtensions
  6.     ' Credits to Tony Tanzillo, Alexander Rivilis, Kerry Brown...
  7.  
  8.     ''' <summary>
  9.     ''' Provides methods to comunicate with AutoLISP.
  10.     ''' </summary>
  11.     Public Class LispExtensions
  12.         <System.Security.SuppressUnmanagedCodeSecurity()> _
  13.         <DllImport("acad.exe", EntryPoint:="acedInvoke", _
  14.         CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Cdecl)> _
  15.         Private Shared Function acedInvoke(args As IntPtr, ByRef result As IntPtr) As Integer
  16.         End Function
  17.  
  18.         ''' <summary>
  19.         ''' Invoke a LISP function.
  20.         ''' The LISP function must be defined as an external subroutine using the c: prefix or invoking vl-acad-defun.
  21.         ''' This is no more mandatory since A2011 as the managed Application.Invoke() method wraps acedInvoke.
  22.         ''' </summary>
  23.         ''' <param name="args">The function name (string) following by the function arguments.</param>
  24.         ''' <returns>The LISP function return value or null if failed.</returns>
  25.         Public Shared Function InvokeLisp(args As ResultBuffer) As ResultBuffer
  26.             Dim ip As IntPtr = IntPtr.Zero
  27.             Dim status As Integer = acedInvoke(args.UnmanagedObject, ip)
  28.             If status = CInt(PromptStatus.OK) AndAlso ip <> IntPtr.Zero Then
  29.                 Return ResultBuffer.Create(ip, True)
  30.             End If
  31.             Return Nothing
  32.         End Function
  33.  
  34.         <System.Security.SuppressUnmanagedCodeSecurity()> _
  35.         <DllImport("acad.exe", EntryPoint:="acedPutSym", _
  36.         CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Cdecl)> _
  37.         Private Shared Function acedPutSym(args As String, result As IntPtr) As Integer
  38.         End Function
  39.  
  40.         ''' <summary>
  41.         ''' Set a LISP variable value.
  42.         ''' </summary>
  43.         ''' <param name="name">The variable name.</param>
  44.         ''' <param name="rb">The variable value</param>
  45.         Public Shared Sub SetLispSym(name As String, rb As ResultBuffer)
  46.             acedPutSym(name, rb.UnmanagedObject)
  47.         End Sub
  48.  
  49.         <System.Security.SuppressUnmanagedCodeSecurity()> _
  50.         <DllImport("acad.exe", EntryPoint:="acedGetSym", _
  51.         CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Cdecl)> _
  52.         Private Shared Function acedGetSym(args As String, ByRef result As IntPtr) As Integer
  53.         End Function
  54.  
  55.         ''' <summary>
  56.         ''' Get a LISP variable value.
  57.         ''' </summary>
  58.         ''' <param name="name">The variable name.</param>
  59.         ''' <returns>The variable value or null if failed.</returns>
  60.         Public Shared Function GetLispSym(name As String) As ResultBuffer
  61.             Dim ip As IntPtr = IntPtr.Zero
  62.             Dim status As Integer = acedGetSym(name, ip)
  63.             If status = CInt(PromptStatus.OK) AndAlso ip <> IntPtr.Zero Then
  64.                 Return ResultBuffer.Create(ip, True)
  65.             End If
  66.             Return Nothing
  67.         End Function
  68.     End Class
  69. End Namespace
  70.  


Felix,

You can add this class to your project and change the namespace or "import" it in you your main class (or module).
Then you'd be able to call the methods using :
LispExtensions.SetLispSym()

Anyway, if you want to use .NET with LISP you have to learn how to deal wit TypedValue and ResultBuffer objects.

Here's a little example to test and show these methods using:

Code - vb.net: [Select]
  1. Imports Autodesk.AutoCAD.ApplicationServices
  2. Imports Autodesk.AutoCAD.DatabaseServices
  3. Imports Autodesk.AutoCAD.EditorInput
  4. Imports Autodesk.AutoCAD.Runtime
  5. Imports AcadExtensions
  6.  
  7. Namespace AcadVbTemplate
  8.  
  9.     Public Class Commands
  10.  
  11.         <CommandMethod("test")> _
  12.         Public Sub Test()
  13.             Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  14.             Dim ed As Editor = doc.Editor
  15.  
  16.             ' create a result buffer containing a LISP list
  17.             Dim input As New ResultBuffer(
  18.                 New TypedValue(CInt(LispDataType.ListBegin)),
  19.                 New TypedValue(CInt(LispDataType.Int16), 12),
  20.                 New TypedValue(CInt(LispDataType.Text), "toto"),
  21.                 New TypedValue(CInt(LispDataType.T_atom)),
  22.                 New TypedValue(CInt(LispDataType.ListEnd)))
  23.  
  24.             ' bind the list to a 'lst1' LISP variable
  25.             LispExtensions.SetLispSym("lst1", input)
  26.  
  27.             ' call the 'foo' Lisp function which binds the reversed list to 'lst2'
  28.             ' (defun foo () (setq lst2 (reverse lst1))) (vl-acad-defun 'foo)
  29.             LispExtensions.InvokeLisp(New ResultBuffer(New TypedValue(CInt(LispDataType.Text), "foo")))
  30.  
  31.             ' get the 'lst2' variable value
  32.             Dim output As ResultBuffer = LispExtensions.GetLispSym("lst2")
  33.  
  34.             ' print the value to the commande line
  35.             For Each tv As TypedValue In output
  36.                 ed.WriteMessage(vbLf & "Type: {0}" & vbTab & "Value: {1}", tv.TypeCode, tv.Value)
  37.             Next
  38.         End Sub
  39.  
  40.     End Class
  41. End Namespace
  42.  
« Last Edit: January 25, 2012, 01:17:17 PM by gile »
Speaking English as a French Frog

FELIX

  • Bull Frog
  • Posts: 241
Re: Getting and Putting Lisp Variables from .NET
« Reply #8 on: January 22, 2012, 06:11:45 PM »
Gile, is excellent, very good, this is almost, not perfect because it is concise, practical.

 Even so thank you all.

 I will make the transfer of variables Autolisp <> VB.NET for the Windows registry.

 OK.
OK.

ZK

  • Guest
Re: Getting and Putting Lisp Variables from .NET
« Reply #9 on: December 03, 2012, 03:35:08 AM »
Hi,

I try to run this example in AutoCAD2013, and have error message...


My button code:
Code: [Select]
private void button4_Click(object sender, EventArgs e)
        {
            ResultBuffer res1 = LispExtensions.GetLispSym("TestVar1");
            MessageBox.Show("\nTestVar1 = ", res1.ToString());           
        }

What can I do?

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Getting and Putting Lisp Variables from .NET
« Reply #10 on: December 03, 2012, 03:50:55 AM »
Hi,

As you probably know, with AutoCAD 2013 version, acad.exe have been splited into two assemblies: acad.exe and accore.dll.
acedInvoke(), acedGetSym() and acedPutSym() methods are now part of accore.dll, so you have to replace acad.exe with accore.dll in the DllImport attribute arguments.
Speaking English as a French Frog

ZK

  • Guest
Re: Getting and Putting Lisp Variables from .NET
« Reply #11 on: December 03, 2012, 05:17:08 AM »
Hi,

As you probably know, with AutoCAD 2013 version, acad.exe have been splited into two assemblies: acad.exe and accore.dll.
acedInvoke(), acedGetSym() and acedPutSym() methods are now part of accore.dll, so you have to replace acad.exe with accore.dll in the DllImport attribute arguments.


Hi,

thank you :) it's work!

regards