.NET

Reply
*Carlos
Message 1 of 9 (360 Views)

Passing arguments and returning values with .NET and LISP

360 Views, 8 Replies
09-04-2005 10:24 AM
Does anyone have an example of passing arguments to a function called from
LISP but written in a .NET language?

It would also be nice to see an example of returning values to the LISP that
called it.

For example, I'd like to write a function like this:

[CommandMethod("DoSomethingToNumber", CommandFlags.Defun)]

and then call it in AutoLISP with something like (command
"DoSomethingToNumber" 25).

I don't even know if this is possible. Any advice is greatly appreciated.

-Carlos
Distinguished Contributor
dmarcotte4
Posts: 195
Registered: ‎04-02-2005
Message 2 of 9 (360 Views)

Re: Passing arguments and returning values with .NET and LISP

09-04-2005 01:47 PM in reply to: *Carlos
Carlos,
I am real new at this c# stuff so you might want to get a second opinion, but this works for getting command arguments into c#. I have no idea how to return a value to lisp.



using System;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

public class CommandWithArg
{
[CommandMethod("MyCommand", CommandFlags.Modal)]
public static void MyCommand()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
PromptStringOptions myPromt = new PromptStringOptions("arg");
myPromt.Message = "arg";
PromptResult pResult = null;
pResult = ed.GetString(myPromt);
//
if (pResult.Status == PromptStatus.OK)
{
string myResult = pResult.StringResult;
acadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage("Mycommand " + myResult);
acadApp.UpdateScreen();
}

}
}

//
//(vl-cmdf “mycommand” “arg”)
*Carlos
Message 3 of 9 (360 Views)

Re: Passing arguments and returning values with .NET and LISP

09-04-2005 04:40 PM in reply to: *Carlos
Hmm,

Thanks for your help, but I don't think I want to be prompting the user for
the arguments. I'll keep this method in mind though in case the need
arises!

Thanks again,
c

wrote in message news:4947446@discussion.autodesk.com...
Carlos,
I am real new at this c# stuff so you might want to get a second opinion,
but this works for getting command arguments into c#. I have no idea how to
return a value to lisp.



using System;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

public class CommandWithArg
{
[CommandMethod("MyCommand", CommandFlags.Modal)]
public static void MyCommand()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
PromptStringOptions myPromt = new PromptStringOptions("arg");
myPromt.Message = "arg";
PromptResult pResult = null;
pResult = ed.GetString(myPromt);
//
if (pResult.Status == PromptStatus.OK)
{
string myResult = pResult.StringResult;
acadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage("Mycommand
" + myResult);
acadApp.UpdateScreen();
}

}
}

//
//(vl-cmdf "mycommand" "arg")
*Tony Tanzillo
Message 4 of 9 (360 Views)

Re: Passing arguments and returning values with .NET and LISP

09-04-2005 08:31 PM in reply to: *Carlos
The proper way to achieve connectivity with LISP, is to
make your managed application a COM server, and use
(vla-getinterfaceobject) to connect to it from LISP, and
call its methods.

While as another post mentioned, you can kludge it by
implementing a command and passing the input via the
(command) function, that also makes it possible for
the user to access, which you don't want to allow.

Here is a sample C# class that's exposed as an ActiveX
object. It exposes one property and one method to COM.
You can create an instance of it from VBA or LISP, and
use it just like any other COM server. Note that if you
implement IExtensionApplication in the same assembly,
its members will be called by the interop when the first
instance of your COM object is created.

There is no need to NETLOAD this, since it is a COM
server whose loading is handed by Windows, just like
any COM server.

/////////////////////////////////////////////////////
// COMExtension.cs copyright (c) 2005 Tony Tanzillo
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace COMExtension
{

// We use this base class to prevent virtual public
// members of System.Object from being made visible to
// COM. Note that Object.GetType() is not virtual, and
// hence, cannot be hidden this way.

[ComVisible(false)]
public class COMHiddenBaseMethods
{
[ComVisible(false)]
public override bool Equals(object obj)
{
return base.Equals (obj);
}

[ComVisible(false)]
public override int GetHashCode()
{
return base.GetHashCode ();
}

[ComVisible(false)]
public override string ToString()
{
return base.ToString ();
}
}

///
/// This class is exposed as a COM object.
///
/// To create an instnace, use vla-getinterfaceobject
/// with the progid that is assigned using the ProgId
/// attribute as shown below.
///
/// If your class has public members that you do not
/// want to be exposed to COM, you should attribute
/// them with [ComVisible(false)], as shown below.
///
/// The ClassInterface attribute is required, and must
/// be either AutoDual or AutoDispatch. For Visual LISP
/// use only, AutoDispatch will work. For early binding
/// from VBA or other ActiveX consumers, AutoDual must
/// be used.
///
/// The ProgId attribute is necessary. The value that
/// you assign to this attribute is what you pass to
/// vla-getinterfaceobject or VB/A's GetObject() to
/// create an instance of this class.
///
///


[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("COMExtension.Class1")]
public class Class1 : COMHiddenBaseMethods, IExtensionApplication
{
public Class1()
{
}

[ComVisible(true)]
public int Increment(int arg)
{
Prompt("MyMethod({0})\n", arg);
return arg + 1;
}

private double m_MyProperty;

[ComVisible(true)]
public double MyProperty
{
get
{
return m_MyProperty;
}
set
{
m_MyProperty = value;
}
}

private static void Prompt(string msg)
{
AcadApp.DocumentManager.MdiActiveDocument.
Editor.WriteMessage(msg);
}

private static void Prompt(string fmt, params object[] args)
{
AcadApp.DocumentManager.MdiActiveDocument.
Editor.WriteMessage(fmt, args);
}

#region IExtensionApplication Members

[ComVisible(false)]
public void Terminate()
{
}

[ComVisible(false)]
public void Initialize()
{
Prompt("\nIExtensionApplication.Initialize() called.\n");
}

#endregion

}
}

//////////////////////////////////
--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2004/2005/2006
http://www.acadxtabs.com

"Carlos" wrote in message news:4947396@discussion.autodesk.com...
Does anyone have an example of passing arguments to a function called from
LISP but written in a .NET language?

It would also be nice to see an example of returning values to the LISP that
called it.

For example, I'd like to write a function like this:

[CommandMethod("DoSomethingToNumber", CommandFlags.Defun)]

and then call it in AutoLISP with something like (command
"DoSomethingToNumber" 25).

I don't even know if this is possible. Any advice is greatly appreciated.

-Carlos
*Carlos
Message 5 of 9 (360 Views)

Re: Passing arguments and returning values with .NET and LISP

09-05-2005 11:48 AM in reply to: *Carlos
Wow,

This totally changes the way I'll be going about this stuff.

Thanks very much for pointing this out to me! It'll take me a while to
understand it, but I'll give it a shot.

-Carlos


"Tony Tanzillo" wrote in message
news:4947498@discussion.autodesk.com...
The proper way to achieve connectivity with LISP, is to
make your managed application a COM server, and use
(vla-getinterfaceobject) to connect to it from LISP, and
call its methods.

While as another post mentioned, you can kludge it by
implementing a command and passing the input via the
(command) function, that also makes it possible for
the user to access, which you don't want to allow.

Here is a sample C# class that's exposed as an ActiveX
object. It exposes one property and one method to COM.
You can create an instance of it from VBA or LISP, and
use it just like any other COM server. Note that if you
implement IExtensionApplication in the same assembly,
its members will be called by the interop when the first
instance of your COM object is created.

There is no need to NETLOAD this, since it is a COM
server whose loading is handed by Windows, just like
any COM server.

/////////////////////////////////////////////////////
// COMExtension.cs copyright (c) 2005 Tony Tanzillo
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace COMExtension
{

// We use this base class to prevent virtual public
// members of System.Object from being made visible to
// COM. Note that Object.GetType() is not virtual, and
// hence, cannot be hidden this way.

[ComVisible(false)]
public class COMHiddenBaseMethods
{
[ComVisible(false)]
public override bool Equals(object obj)
{
return base.Equals (obj);
}

[ComVisible(false)]
public override int GetHashCode()
{
return base.GetHashCode ();
}

[ComVisible(false)]
public override string ToString()
{
return base.ToString ();
}
}

///
/// This class is exposed as a COM object.
///
/// To create an instnace, use vla-getinterfaceobject
/// with the progid that is assigned using the ProgId
/// attribute as shown below.
///
/// If your class has public members that you do not
/// want to be exposed to COM, you should attribute
/// them with [ComVisible(false)], as shown below.
///
/// The ClassInterface attribute is required, and must
/// be either AutoDual or AutoDispatch. For Visual LISP
/// use only, AutoDispatch will work. For early binding
/// from VBA or other ActiveX consumers, AutoDual must
/// be used.
///
/// The ProgId attribute is necessary. The value that
/// you assign to this attribute is what you pass to
/// vla-getinterfaceobject or VB/A's GetObject() to
/// create an instance of this class.
///
///


[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("COMExtension.Class1")]
public class Class1 : COMHiddenBaseMethods, IExtensionApplication
{
public Class1()
{
}

[ComVisible(true)]
public int Increment(int arg)
{
Prompt("MyMethod({0})\n", arg);
return arg + 1;
}

private double m_MyProperty;

[ComVisible(true)]
public double MyProperty
{
get
{
return m_MyProperty;
}
set
{
m_MyProperty = value;
}
}

private static void Prompt(string msg)
{
AcadApp.DocumentManager.MdiActiveDocument.
Editor.WriteMessage(msg);
}

private static void Prompt(string fmt, params object[] args)
{
AcadApp.DocumentManager.MdiActiveDocument.
Editor.WriteMessage(fmt, args);
}

#region IExtensionApplication Members

[ComVisible(false)]
public void Terminate()
{
}

[ComVisible(false)]
public void Initialize()
{
Prompt("\nIExtensionApplication.Initialize() called.\n");
}

#endregion

}
}

//////////////////////////////////
--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2004/2005/2006
http://www.acadxtabs.com

"Carlos" wrote in message
news:4947396@discussion.autodesk.com...
Does anyone have an example of passing arguments to a function called from
LISP but written in a .NET language?

It would also be nice to see an example of returning values to the LISP that
called it.

For example, I'd like to write a function like this:

[CommandMethod("DoSomethingToNumber", CommandFlags.Defun)]

and then call it in AutoLISP with something like (command
"DoSomethingToNumber" 25).

I don't even know if this is possible. Any advice is greatly appreciated.

-Carlos
*Tony Tanzillo
Message 6 of 9 (360 Views)

Re: Passing arguments and returning values with .NET and LISP

09-05-2005 08:45 PM in reply to: *Carlos
Actually, there seems to be a problem with the code
I posted. I think it has to do with the fact that the
class exposed to COM implements IExtensionApplication.

My guess is that you should not have a class that's
exposed as a COM object implement this interface.

If you need IExtensionApplication, implement in on a
different class that is not exposed to COM.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2004/2005/2006
http://www.acadxtabs.com

"Carlos" wrote in message news:4947714@discussion.autodesk.com...
Wow,

This totally changes the way I'll be going about this stuff.

Thanks very much for pointing this out to me! It'll take me a while to
understand it, but I'll give it a shot.

-Carlos


"Tony Tanzillo" wrote in message
news:4947498@discussion.autodesk.com...
The proper way to achieve connectivity with LISP, is to
make your managed application a COM server, and use
(vla-getinterfaceobject) to connect to it from LISP, and
call its methods.

While as another post mentioned, you can kludge it by
implementing a command and passing the input via the
(command) function, that also makes it possible for
the user to access, which you don't want to allow.

Here is a sample C# class that's exposed as an ActiveX
object. It exposes one property and one method to COM.
You can create an instance of it from VBA or LISP, and
use it just like any other COM server. Note that if you
implement IExtensionApplication in the same assembly,
its members will be called by the interop when the first
instance of your COM object is created.

There is no need to NETLOAD this, since it is a COM
server whose loading is handed by Windows, just like
any COM server.

/////////////////////////////////////////////////////
// COMExtension.cs copyright (c) 2005 Tony Tanzillo
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace COMExtension
{

// We use this base class to prevent virtual public
// members of System.Object from being made visible to
// COM. Note that Object.GetType() is not virtual, and
// hence, cannot be hidden this way.

[ComVisible(false)]
public class COMHiddenBaseMethods
{
[ComVisible(false)]
public override bool Equals(object obj)
{
return base.Equals (obj);
}

[ComVisible(false)]
public override int GetHashCode()
{
return base.GetHashCode ();
}

[ComVisible(false)]
public override string ToString()
{
return base.ToString ();
}
}

///
/// This class is exposed as a COM object.
///
/// To create an instnace, use vla-getinterfaceobject
/// with the progid that is assigned using the ProgId
/// attribute as shown below.
///
/// If your class has public members that you do not
/// want to be exposed to COM, you should attribute
/// them with [ComVisible(false)], as shown below.
///
/// The ClassInterface attribute is required, and must
/// be either AutoDual or AutoDispatch. For Visual LISP
/// use only, AutoDispatch will work. For early binding
/// from VBA or other ActiveX consumers, AutoDual must
/// be used.
///
/// The ProgId attribute is necessary. The value that
/// you assign to this attribute is what you pass to
/// vla-getinterfaceobject or VB/A's GetObject() to
/// create an instance of this class.
///
///


[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("COMExtension.Class1")]
public class Class1 : COMHiddenBaseMethods, IExtensionApplication
{
public Class1()
{
}

[ComVisible(true)]
public int Increment(int arg)
{
Prompt("MyMethod({0})\n", arg);
return arg + 1;
}

private double m_MyProperty;

[ComVisible(true)]
public double MyProperty
{
get
{
return m_MyProperty;
}
set
{
m_MyProperty = value;
}
}

private static void Prompt(string msg)
{
AcadApp.DocumentManager.MdiActiveDocument.
Editor.WriteMessage(msg);
}

private static void Prompt(string fmt, params object[] args)
{
AcadApp.DocumentManager.MdiActiveDocument.
Editor.WriteMessage(fmt, args);
}

#region IExtensionApplication Members

[ComVisible(false)]
public void Terminate()
{
}

[ComVisible(false)]
public void Initialize()
{
Prompt("\nIExtensionApplication.Initialize() called.\n");
}

#endregion

}
}

//////////////////////////////////
--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2004/2005/2006
http://www.acadxtabs.com

"Carlos" wrote in message
news:4947396@discussion.autodesk.com...
Does anyone have an example of passing arguments to a function called from
LISP but written in a .NET language?

It would also be nice to see an example of returning values to the LISP that
called it.

For example, I'd like to write a function like this:

[CommandMethod("DoSomethingToNumber", CommandFlags.Defun)]

and then call it in AutoLISP with something like (command
"DoSomethingToNumber" 25).

I don't even know if this is possible. Any advice is greatly appreciated.

-Carlos
Distinguished Contributor
cwanless
Posts: 225
Registered: ‎12-08-2003
Message 7 of 9 (360 Views)

Re: Passing arguments and returning values with .NET and LISP

06-22-2007 03:06 PM in reply to: *Carlos
Hi Tony, I am having problems getting your example to work, the lisp code I have put together does not load the object. I don't know what I am doing wrong, but here is my lisp code.

(setq $acad (vlax-get-acad-object))
(setq vbstrcls (vla-GetInterfaceObject $acad "COMExtension.Class1"))

(setq out (vlax-invoke-method vbstrcls "Prompt"))
(out "test")
(vlax-release-object vbstrcls)
(vlax-release-object $acad)


can anyone provide working exampe projects that I could use to get this working for me?

Thansk Chad Wanless
*Tony Tanzillo
Message 8 of 9 (360 Views)

Re: Passing arguments and returning values with .NET and LISP

06-22-2007 05:56 PM in reply to: *Carlos
Chad - What happens when you call vla-GetInterfaceObject ?

Have you tried connecting to the COM server from VBA ?

Also, in 2007 or later, you can define LISP functions in
.NET rather than have to use COM.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

wrote in message news:5635962@discussion.autodesk.com...
Hi Tony, I am having problems getting your example to work, the lisp code I have put together does not load the object. I don't know what I am doing wrong, but here is my lisp code.

(setq $acad (vlax-get-acad-object))
(setq vbstrcls (vla-GetInterfaceObject $acad "COMExtension.Class1"))

(setq out (vlax-invoke-method vbstrcls "Prompt"))
(out "test")
(vlax-release-object vbstrcls)
(vlax-release-object $acad)


can anyone provide working exampe projects that I could use to get this working for me?

Thansk Chad Wanless
*Tony Tanzillo
Message 9 of 9 (360 Views)

Re: Passing arguments and returning values with .NET and LISP

06-23-2007 01:30 AM in reply to: *Carlos
Chad - The problem is in the COM server.

It may not be registered correctly.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

"Tony Tanzillo" wrote in message news:5636054@discussion.autodesk.com...
Chad - What happens when you call vla-GetInterfaceObject ?

Have you tried connecting to the COM server from VBA ?

Also, in 2007 or later, you can define LISP functions in
.NET rather than have to use COM.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

wrote in message news:5635962@discussion.autodesk.com...
Hi Tony, I am having problems getting your example to work, the lisp code I have put together does not load the object. I don't know what I am doing wrong, but here is my lisp code.

(setq $acad (vlax-get-acad-object))
(setq vbstrcls (vla-GetInterfaceObject $acad "COMExtension.Class1"))

(setq out (vlax-invoke-method vbstrcls "Prompt"))
(out "test")
(vlax-release-object vbstrcls)
(vlax-release-object $acad)


can anyone provide working exampe projects that I could use to get this working for me?

Thansk Chad Wanless
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.