.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Passing arguments and returning values with .NET and LISP

8 REPLIES 8
Reply
Message 1 of 9
Anonymous
1469 Views, 8 Replies

Passing arguments and returning values with .NET and LISP

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
8 REPLIES 8
Message 2 of 9
dmarcotte4
in reply to: Anonymous

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”)
Message 3 of 9
Anonymous
in reply to: Anonymous

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")
Message 4 of 9
Anonymous
in reply to: Anonymous

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
Message 5 of 9
Anonymous
in reply to: Anonymous

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
Message 6 of 9
Anonymous
in reply to: Anonymous

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
Message 7 of 9
cwanless
in reply to: Anonymous

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
Message 8 of 9
Anonymous
in reply to: Anonymous

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
Message 9 of 9
Anonymous
in reply to: Anonymous

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

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost