Results 1 to 10 of 18

Thread: Unclear on syntax for returning from a lisp function created in c#

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Active Member
    Join Date
    2008-02
    Location
    Toronto, On
    Posts
    59
    Login to Give a bone
    0

    Default Unclear on syntax for returning from a lisp function created in c#

    So I'm trying to understand the process for creating a Lisp function in c# .net.


    Code:
    public class LispException : System.Exception
            {
                public LispException(string msg) : base(msg) { }
            }
    
            public class TooFewArgsException : LispException
            {
                public TooFewArgsException() : base("too few arguments") { }
            }
    
            public class TooManyArgsException : LispException
            {
                public TooManyArgsException() : base("too many arguments") { }
            }
    
            public class ArgumentTypeException : LispException
            {
                public ArgumentTypeException(string s, TypedValue tv)
                    : base(string.Format("Bad argument type: {0} {1}", s, tv.TypeCode == (int)LispDataType.Nil ? "nil" : tv.Value)) { }
            }
    
    
    
    
    
            [LispFunction("DoubleValue")]
            public object DoubleValue(ResultBuffer argBuffer)
            {
                Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
                Object Res = new ResultBuffer();
    
                try
                {
                    if (argBuffer == null)
                    {
                        throw new TooFewArgsException();
                    }
                    else
                    {
                        TypedValue[] argArray = argBuffer.AsArray();
                        int ArrayLen = argArray.Length;
    
                        if (ArrayLen > 1)
                        {
                            throw new TooManyArgsException();
                        }
    
                        else
                        {
    
                            if (argArray[0].TypeCode == (short)LispDataType.Double)
                            {
                                Res = ((double)argArray[0].Value) * 2.0;
                            }
                            else if (argArray[0].TypeCode == (short)LispDataType.Int16)
                            {
                                Res = ((Int16)argArray[0].Value) * 2;
                            }
                            else if (argArray[0].TypeCode == (short)LispDataType.Int32)
                            {
                                Res = ((Int32)argArray[0].Value) * 2;
                            }
                            else
                            {
                                throw new ArgumentTypeException("numberp", argArray[0]);
                            }
                        }
                    }
    
                    return Res;
                }//end try
    
                
                catch (LispException ex)
                {
                    ed.WriteMessage("\n; error: {0}\n", ex.Message);
                    return null;
                }
    
                catch (Autodesk.AutoCAD.Runtime.Exception ex)
                {
                    ed.WriteMessage("\nAutoCAD error: {0}\n", ex.Message);
                    return null;
                }
    
                catch (System.Exception ex)
                {
                    ed.WriteMessage("\nSystem error: {0}\n", ex.Message);
                    return null;
                }
            }

    I can netload this without a problem, and it does what it's supposed to do...up to a point...

    Code:
    Command: (setq Num 12)
    12
    
    Command: (setq Num (DoubleValue Num))
    24
    
    Command: (setq Num (DoubleValue 12.34))
    24.68
    
    Command: (setq Num (abs))
    ; error: too few arguments
    
    Command: !Num
    24.68
    
    Command: (setq Num (DoubleValue))
    
    ; error: too few arguments
    nil
    
    Command: !Num
    nil
    Notice that the call to (abs) with no arguments resulted in an error, but (abs) didn't return a value to the setq, so Num kept it's previous value.
    How do I create a Lisp function in c# that will properly catch exceptions, but not return nil to the calling function, just like normal autolisp functions?

    Thanks!

  2. #2
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,719
    Login to Give a bone
    0

    Default Re: Unclear on syntax for returning from a lisp function created in c#

    Couple of things....

    Quote Originally Posted by JaCAD View Post
    So I'm trying to understand the process for creating a Lisp function in c# .net.

    Code:
    public class LispException : System.Exception
            {
                public LispException(string msg) : base(msg) { }
            }
    
            public class TooFewArgsException : LispException
            {
                public TooFewArgsException() : base("too few arguments") { }
            }
    
            public class TooManyArgsException : LispException
            {
                public TooManyArgsException() : base("too many arguments") { }
            }
    
            public class ArgumentTypeException : LispException
            {
                public ArgumentTypeException(string s, TypedValue tv)
                    : base(string.Format("Bad argument type: {0} {1}", s, tv.TypeCode == (int)LispDataType.Nil ? "nil" : tv.Value)) { }
            }
    Firstly, when copying someone else's code, be sure to credit them, and include a link when possible. I can recognize Gile's LispException Classes anywhere, as he shared them with me when I was first learning to work with LispFunction Methods.


    Quote Originally Posted by JaCAD View Post
    I can netload this without a problem, and it does what it's supposed to do...up to a point...

    Code:
    Command: (setq Num 12)
    12
    
    Command: (setq Num (DoubleValue Num))
    24
    
    Command: (setq Num (DoubleValue 12.34))
    24.68
    
    Command: (setq Num (abs))
    ; error: too few arguments
    
    Command: !Num
    24.68
    
    Command: (setq Num (DoubleValue))
    
    ; error: too few arguments
    nil
    
    Command: !Num
    nil
    Notice that the call to (abs) with no arguments resulted in an error, but (abs) didn't return a value to the setq, so Num kept it's previous value.
    How do I create a Lisp function in c# that will properly catch exceptions, but not return nil to the calling function, just like normal autolisp functions?
    Simple, either return false, or a ResultBuffer with a Nil LispDataType... Just be sure to handle any Exception(s), as not every LispFunction Method will do simple Math calculations.
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  3. #3
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,719
    Login to Give a bone
    0

    Default Re: Unclear on syntax for returning from a lisp function created in c#

    Consider this adaptation:

    Code:
    using Autodesk.AutoCAD.DatabaseServices;
    using Autodesk.AutoCAD.Runtime;
    
    using System;
    
    [assembly: CommandClass(typeof(AUGI.Sample.LispFunctions.Commands))]
    
    namespace AUGI.Sample.LispFunctions
    {
        public class Commands
        {
            [LispFunction("2X")]
            public object Double(ResultBuffer resbuf)
            {
                if (resbuf == null)
                    return false;
    
                TypedValue[] args = resbuf.AsArray();
    
                if (args.Length != 1)
                    return false;
    
                TypedValue arg = args[0];
                short type = arg.TypeCode;
    
                if (type == (short)LispDataType.Double)
                    return ((double)arg.Value) * 2.0;
    
                if (type == (short)LispDataType.Int16)
                    return ((Int16)arg.Value) * 2;
    
                if (type == (short)LispDataType.Int32)
                    return ((Int32)arg.Value) * 2;
    
                return false;
            }
        }
    }
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  4. #4
    I could stop if I wanted to
    Join Date
    2007-08
    Posts
    202
    Login to Give a bone
    0

    Default Re: Unclear on syntax for returning from a lisp function created in c#

    Hi,
    How do I create a Lisp function in c# that will properly catch exceptions, but not return nil to the calling function, just like normal autolisp functions?
    It returns nil because your error handlers ends with: "return null;".
    To avoid this, you can re-throw the exception after having displayed the error message:
    Code:
    catch (LispException ex)
                {
                    MgdAcApplication.ShowAlertDialog(ex.Message);
                    throw;
                }
    
                catch (Autodesk.AutoCAD.Runtime.Exception ex)
                {
                    MgdAcApplication.ShowAlertDialog(ex.Message);
                    throw;
                }
    
                catch (System.Exception ex)
                {
                    MgdAcApplication.ShowAlertDialog(ex.Message);
                    throw;
                }
    PS: BlackBox, your adaptation should always return nil in case an exception is raised (nil stands for false too).
    Last edited by 'gile'; 2013-04-09 at 11:18 AM.

  5. #5
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,719
    Login to Give a bone
    0

    Default Re: Unclear on syntax for returning from a lisp function created in c#

    Quote Originally Posted by 'gile' View Post
    PS: BlackBox, your adaptation should always return nil in case an exception is raised (nil stands for false too).
    It (my code) does always return Nil (false) in place of an Exception... However, unless I've overlooked something, Exception handling is only necessary when you've not accounted for a possible Exception through code logic... As I am using logical tests for each step, this is not necessary, as there are no Exceptions thrown.
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  6. #6
    I could stop if I wanted to
    Join Date
    2007-08
    Posts
    202
    Login to Give a bone
    0

    Default Re: Unclear on syntax for returning from a lisp function created in c#

    Quote Originally Posted by BlackBox View Post
    It (my code) does always return Nil (false) in place of an Exception... However, unless I've overlooked something, Exception handling is only necessary when you've not accounted for a possible Exception through code logic... As I am using logical tests for each step, this is not necessary, as there are no Exceptions thrown.
    I do not think so. An invalid input (as an invalid number or type of argument) have to throw an exception instead of returning a valid LISP value: nil.
    Your code hides the exception and may cause an exception later in the calling function:

    Code:
    (setq a (2x))
    ;; ...
    (princ (itoa a))
    ; error: Bad argument type: fixnump: nil

  7. #7
    Active Member
    Join Date
    2008-02
    Location
    Toronto, On
    Posts
    59
    Login to Give a bone
    0

    Default Re: Unclear on syntax for returning from a lisp function created in c#

    Quote Originally Posted by 'gile' View Post
    Hi,


    It returns nil because your error handlers ends with: "return null;".
    To avoid this, you can re-throw the exception after having displayed the error message:
    Code:
    catch (LispException ex)
                {
                    MgdAcApplication.ShowAlertDialog(ex.Message);
                    throw;
                }
    
                catch (Autodesk.AutoCAD.Runtime.Exception ex)
                {
                    MgdAcApplication.ShowAlertDialog(ex.Message);
                    throw;
                }
    
                catch (System.Exception ex)
                {
                    MgdAcApplication.ShowAlertDialog(ex.Message);
                    throw;
                }
    PS: BlackBox, your adaptation should always return nil in case an exception is raised (nil stands for false too).

    Thanks Gile, this is the functionality I was looking for. Thanks also for your LispException classes.

    Is there a way to suppress the error stack which dumps to the command prompt in the instance of an exception?

    Thanks!

  8. #8
    I could stop if I wanted to
    Join Date
    2007-08
    Posts
    202
    Login to Give a bone
    0

    Default Re: Unclear on syntax for returning from a lisp function created in c#

    Is there a way to suppress the error stack which dumps to the command prompt in the instance of an exception?
    Maybe, but I don't know which. That's why I use the Application.ShowAlertDialog() method to prevent the user/coder that an error occured.

Similar Threads

  1. Function "order and resize array" not returning values
    By CADfunk MC in forum VBA/COM Interop
    Replies: 8
    Last Post: 2015-01-06, 02:06 PM
  2. Common Lisp Object System (CLOS) Syntax
    By peter in forum Bridging the Gap: LISP -> .NET -> LISP
    Replies: 14
    Last Post: 2014-02-17, 02:20 AM
  3. LISP routine returning bad function error
    By playerdraft in forum AutoLISP
    Replies: 2
    Last Post: 2011-06-15, 04:38 PM
  4. Returning a SYMBOL using VB.Net Lisp Function
    By bweir in forum Dot Net API
    Replies: 0
    Last Post: 2007-05-11, 03:56 PM
  5. Is it possible to fill in a gap in an object created with the push/pull function?
    By bkolodzaike in forum AutoCAD 3D (2007 and above)
    Replies: 4
    Last Post: 2007-03-13, 01:26 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •