Call AutoLISP Function from C# Code

Call AutoLISP Function from C# Code

Anonymous
Not applicable
5,482 Views
10 Replies
Message 1 of 11

Call AutoLISP Function from C# Code

Anonymous
Not applicable

I'm trying to write a function to simplify the process of calling an AutoLISP function from C#.NET. Right now my code is structured like this:

 

public static class LanguageExtensions
{
    public static List<String> executeLISPFunction(string functionName)
    {
         List<String> funcReturnValues = new List<String>();

         //Call lisp function and set funcReturnValues equal to the values the AutoLISP function returns

         return funcReturnValues;
     }
}

 

I need to know if the approach I'm taking is possible and if so how I would replace the comment with code that does what the comment describes. Any help would be greatly appreciated!

 

0 Likes
5,483 Views
10 Replies
Replies (10)
Message 2 of 11

_gile
Consultant
Consultant

Hi,

 

You may have a look at the Autodesk.AutoCAD.ApplicationServices.Application.Invoke() method.

Note that if the LISP function called returns a LISP list, it will be converted in .NET into a ResultBuffer.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 11

dgorsman
Consultant
Consultant

To be avoided unless absolutely, full stop, no other option.  Otherwise put the effort into converting the LISP into dotNET - you'll save yourself a *lot* of hair pulling.  With some judicious writing you can even make the necessary parts of the functions callable from existing LISP.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


0 Likes
Message 4 of 11

Anonymous
Not applicable

It wants me to pass a ResultBuffer in as an argument. Should I create a ResultBuffer with the args I want to pass into the LISP function and pass that in?

0 Likes
Message 5 of 11

_gile
Consultant
Consultant

Yes, and the first item in the ResultBuffer must be the LISP function name (as string).

if the called function is not prefixed with 'c:', you have to use the vl-acad-defun LISP function to make it is accessible from an external ObjectARX or .NET application.

 

But, I agree with dgorsman, avoid this kind of stuff if you can.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 11

JamesMaeding
Advisor
Advisor

the problem with avoiding mixing lisp and .net is most environments that customize have a fair amount of lisp that runs stable, and you cannot just port over to .net fast and expect the same stability/behavior.  Different issues arise in .net than lisp.

 

I try to stay within a language too, but the more important thing is knowing how to mix them in a predictable stable manner.

I do a lot of what I call "simple" mixing, and have found one critical issue:

.net modifies the list a lisp function returns.

It turns certain things like lists of three integers into a point in the rbuff codes.

 

Since I do not want to babysit that in every place I do mixing, I send only a single string as the parameter/return val back and forth between .net and lisp.

That string is the serialized resultbuffer/list, which .net always keeps intact.

So you must have serializing/deserializing functions on both ends, but its fast and stable.

 

An example case I did this for is the colordialog, which is missing truecolor tab in the lisp version.

I made a .net lispfunction using the .net color dialog, and send back the color chosen.

If rgb, that is three integers which .net screws up, so serializing is better.

You could do simple comma delim for simple lists, but my other lists are not simple so...


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

0 Likes
Message 7 of 11

dgorsman
Consultant
Consultant

I mix quite a bit, but only in one direction.  I port code to dotNET and make it callable from LISP but not in the other direction.  With lots of LISP code, I have made sure it is well constructed, black-box style coding so whats in the box doesn't matter.  I just swap one box for another.  A good example of this is our standards system - I've moved from INI/CFG data files to XML, from LISP to dotNET, and from dynamic accesss to version-controlled cached data, with no problems in stability and minimal work.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


0 Likes
Message 8 of 11

hencoop
Advisor
Advisor

@JamesMaeding I realize this post is several years old; however, it appears that you know how to do what I need to do.

 

I have a lisp routine that gathers Pipe Network object properties and makes use of them.  Everything works fine as I use the structure description to glean the size (assumed to be the same as 'InnerDiameter) as an alternative to (VLAX-GET-PROPERTY <structure object> 'InnerDiameter) which does not work.  Since the description can be anything (including incorrect) I would like to get the property using C#.

 

If possible, I need to know how I can tell C# which specific structure my lisp function is examining and have C# get its 'InnerDiameter property and return it to my autolisp function.

AutoCAD User since 1989. Civil Engineering Professional since 1983
Product Version: 13.6.1963.0 Civil 3D 2024.4.1 Update Built on: U.202.0.0 AutoCAD 2024.1.6
                        27.0.37.14 Autodesk AutoCAD Map 3D 2024.0.1
                        8.6.52.0 AutoCAD Architecture 2024
0 Likes
Message 9 of 11

hencoop
Advisor
Advisor

@JamesMaeding I think I've found the help I need here: https://www.theswamp.org/index.php?topic=35714.0 

AutoCAD User since 1989. Civil Engineering Professional since 1983
Product Version: 13.6.1963.0 Civil 3D 2024.4.1 Update Built on: U.202.0.0 AutoCAD 2024.1.6
                        27.0.37.14 Autodesk AutoCAD Map 3D 2024.0.1
                        8.6.52.0 AutoCAD Architecture 2024
0 Likes
Message 10 of 11

JamesMaeding
Advisor
Advisor

@hencoop 

Looks like you found a good example.

A lisp list in c# and C++ is a resultbuffer. They should have saved themselves the typing and called it a list from the start!

One thing I do is only send one string back and forth between lisp and .net. That string is a "serialized" list, and each side has functions to pack and unpack the string to a list. The reason is a bug related to a list of 3 reals or ints being interpreted as a point. Its been too long for me to remember the specifics but I abandoned using lots of dxf code pairs long ago. You can get away with it until you don't, may never hit you.

 

Another trick I ran into is this does not all work great with modeless dialogs. On a few functions, I use .net to set a lisp global variable instead of passing the string. The lisp function knows to read that var after the call and I get around it. Its like a bulletin board approach - definitely not first choice but works.

 


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

0 Likes
Message 11 of 11

hencoop
Advisor
Advisor

@JamesMaeding  Thank you.  I thought those words but as I was shutting things down this evening I realized I never said them to you.

AutoCAD User since 1989. Civil Engineering Professional since 1983
Product Version: 13.6.1963.0 Civil 3D 2024.4.1 Update Built on: U.202.0.0 AutoCAD 2024.1.6
                        27.0.37.14 Autodesk AutoCAD Map 3D 2024.0.1
                        8.6.52.0 AutoCAD Architecture 2024
0 Likes