LsAdsInvoke Internal Error

LsAdsInvoke Internal Error

office
Enthusiast Enthusiast
849 Views
2 Replies
Message 1 of 3

LsAdsInvoke Internal Error

office
Enthusiast
Enthusiast

I have an issue with the result buffer.

 

        [LispFunction("TestType")]
        public static object TestType(ResultBuffer resBufIn)
        {
            try
            {
                if (resBufIn != null)
                {
                    TypedValue[] tvArr = resBufIn.AsArray();
                    int length = tvArr.Length;
                    if (length > 0)
                    {
                        MessageBox.Show("TypeCode: " + tvArr[0].TypeCode.ToString() + Environment.NewLine + "Value: " + tvArr[0].Value.ToString());
                    }
                }
            }
            catch { }
            return null;
        }

1) If I call the (testtype (list 221 10 10)) in vlide it gives me the LsAdsInvoke Internal Error.

2) If I call the (testtype (list 10 10 10)) in vlide, the messagebox shows for the typecode 10 and value (10,10,0). I think it should be 5009 (Point3d) typecode with the (10,10,10) value.

 

Any idea, how to get rid of the LsAdsInvoke error and solve the typecode problem?

0 Likes
Accepted solutions (1)
850 Views
2 Replies
Replies (2)
Message 2 of 3

_gile
Consultant
Consultant
Accepted solution

Hi,

The main difficulty when trying to play with AutoLISP and C# is that the first is dynamicly (not) typed and the second is strongly and staticly typed.

With AutoLISP, a list of 2 or 3 (real or integer) numbers can be used as a point or a vector. The interpretor can convert this list into a list of 3 real numbers (double) to use it as a Point3d. (0 0), (0 0 0), (0.0 0.0), (0.0 0.0 0.0) can be interpreted the same.

The AutoCAD .NET API has a specific Point2d, Point3d, Vector2d and Vector3d types.

AutoLISP can also interpret a list of 3 or 4 numbers as a DXF data when the first one is an integer which corresponds to a valid DXF group code, e.g.: (10 0.0 0.0 0.0) which .NET corresponding value is: TypedValue(10, Point3d.Origin).

 

That said, those who implemented the .NET LispFunction API thaught it should be a good thing to implicitly convert some type of list of numbers passed as argument to the LispFunction method into specific TypedValue instances as Point2d, Point3d, DXF list...or worst, throw an error in case of "invalid DXF list".

IMO they should have let the end user (developer) decide how to convert a list of numbers.

 

You can do some tests with the following function:

        [LispFunction("TestType")]
        public static object TestType(ResultBuffer resBufIn)
        {
                    var ed = Application.DocumentManager.MdiActiveDocument.Editor;
            try
            {
                if (resBufIn != null)
                {
                    TypedValue[] tvArr = resBufIn.AsArray();
                    foreach (var tv in tvArr)
                    {
                        ed.WriteMessage($"TypeCode: {(LispDataType)tv.TypeCode}\tValue: {tv.Value}\n");
                    }
                }
            }
            catch(System.Exception ex)
            {
                ed.WriteMessage($"{ex.Message}\n");
            }
            // return the resBufIn to see how it have been converted on the .NET side
            return resBufIn;
        }

Some results:

Command: (testType '(0 0))
TypeCode: Point2d    Value: (0,0)
((0.0 0.0))

Command: (testType '(0 0 0))
TypeCode: Point3d    Value: (0,0,0)
((0.0 0.0 0.0))

Command: (testType '(10 10 10))
TypeCode: 10      Value: (10,10,0)
((10 10.0 10.0 0.0))

Command: (testType '(10.0 10 10))
TypeCode: Point3d    Value: (10,10,10)
((10.0 10.0 10.0))

Command: (testType '(19 10 10))
eInvalidResBuf
((19 10.0 10.0 0.0))

Command: (testType '(10 10 10 10))
TypeCode: 10      Value: (10,10,10)
((10 10.0 10.0 10.0))

Command: (testType '(10.0 10 10 10))
TypeCode: ListBegin      Value: -1
TypeCode: Double   Value: 10
TypeCode: Int16  Value: 10
TypeCode: Int16  Value: 10
TypeCode: Int16  Value: 10
TypeCode: ListEnd    Value: -1
(10.0 10 10 10)

 

As you can see, the only way to ensure the 3 numbers  list argument is interpreted as a Point3d is to explicitly write real numbers (at least the first one) on the LISP side (which not an habit with a dynamic typed language).

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 3

office
Enthusiast
Enthusiast

Hi @_gile 

I already figured out that is need to be converted to real numbers, at least the first one in the integer list 😊

I thought there is something else in C# that you can do without manipulating the integer list in lisp before passing it to result buffer.

If you have an integer list with a length of less than 5, you have to convert it to a list with real numbers and pass it to the result buffer. If the length of the integer list is 5 or greater, you don't have to manipulate it to real numbers because there will be no error or typecode problem.

 

Thanks for your help and time @_gile . I like your answers and solutions 😎

0 Likes