Besides .NET, AutoCAD has another API, Autolisp, and it's been around for decades (your CAD department may already rely on several Autolisp programs)! Learn how the AutoCAD .NET API can work with Autolisp.
Define a LISP function the same way we've defined commands. Use the LispFunction
attribute instead of the CommandMethod
attribute.
In an Autolisp program, define a function which, when executed, will call the method that is tagged with the
LispFunction
attribute in our .NET project. In this case, we'll define a LispFunction(fizzbuzz)
, named for the notorious software development interview question. When(fizzbuzz)
is called from Autolisp, it will call the .NET methodfizzBuzz_net
:using System; using System.Collections.Generic; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.Windows; using Autodesk.Windows; // This line is not mandatory, but improves loading performances [assembly: CommandClass(typeof(Ch10AcadPlugin.MyCommands))] namespace Ch10AcadPlugin { public class MyCommands { //Lisp function to call .NET fizzbuzz function [LispFunction("fizzbuzz")] static public ResultBuffer fizzBuzz_net(ResultBuffer args) { Editor ed = default(Editor); ed = Autodesk.AutoCAD.ApplicationServices.Application. DocumentManager.MdiActiveDocument.Editor; //Ensure there are arguments passed in if (args == null) { ed.WriteMessage("No arguments" + System.Environment.NewLine); return args; } else { Array argsArray = null; argsArray = args.AsArray();
Use a ResultBuffer to pass arguments to
fizzBuzz_net
. Put the arguments in an array:if (argsArray.Length > 0) { string myArg1 = ""; //Get the arguments that were passed in TypedValue myTypeVal = default(TypedValue); myTypeVal = (TypedValue)argsArray.GetValue(0); myArg1 = (string)myTypeVal.Value; for (int i = 1; i <= 100; i++) { if (i % 15 == 0) { //Not a multiple of 3 and 5 ed.WriteMessage(System.Environment.NewLine + "FizzBuzz"); } else if (i % 3 == 0) { //Not a multiple of 3 ed.WriteMessage(System.Environment.NewLine + "Fizz"); } else if (i % 5 == 0) { //Not a multiple of 5 ed.WriteMessage(System.Environment.NewLine + "Buzz"); } else { //Not a multiple of 3 or 5 ed.WriteMessage(System.Environment.NewLine + i.ToString()); } }
Modify the contents of the
ResultBuffer
and pass it back to the calling function://Modify the string value from the Result Buffer myArg1 += " completed!"; // Package data to send back to calling lisp //function ResultBuffer resBuf = default(ResultBuffer); resBuf = new ResultBuffer(new TypedValue( Convert.ToInt32(LispDataType.Text), myArg1)); return resBuf; } else { ed.WriteMessage("Not enough arguments" + System.Environment.NewLine); return args; } } } } }
Enter a simple Autolisp function at the command line to call the .NET LispFunction.
We defined a .NET LispFunction to respond to an Autolisp function (fizzbuzz arg)
. In Autolisp syntax, the function name comes immediately after the opening parenthesis.
When we type in (fizzbuzz "FIZZBUZZ")
, we are calling a function named fizzbuzz
and passing in a string argument FIZZBUZZ
. The .NET LispFunction fizzBuzz_net
expects a single ResultBuffer argument. We carry out the actual fizzbuzz
sequence in our .NET function. The string argument that we passed in is also modified by our .NET code, and returned (in a ResultBuffer) back to the calling Autolisp function. That's why we see the modified FIZZBUZZ string in the command prompt.