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

acedGetSym and acedPutSym in .NET applications

5 REPLIES 5
Reply
Message 1 of 6
Anonymous
1970 Views, 5 Replies

acedGetSym and acedPutSym in .NET applications

Hello, All!
I've wrote a class, which can be helpful in .NET for getting/puttings value of lisp-variables:

[code]
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;

[assembly: CommandClass(typeof(Rivilis.AcadLispSym))]

namespace Rivilis
{
public class AcadLispSym
{
//
// From adscodes.h :
//
// Type of resbuf element
const int RTNONE = 5000; /* No result */
const int RTREAL = 5001; /* Real number */
const int RTPOINT = 5002; /* 2D point X and Y only */
const int RTSHORT = 5003; /* Short integer */
const int RTANG = 5004; /* Angle */
const int RTSTR = 5005; /* String */
const int RTENAME = 5006; /* Entity name */
const int RTPICKS = 5007; /* Pick set */
const int RTORINT = 5008; /* Orientation */
const int RT3DPOINT = 5009; /* 3D point - X, Y, and Z */
const int RTLONG = 5010; /* Long integer */
const int RTVOID = 5014; /* Blank symbol */
const int RTLB = 5016; /* list begin */
const int RTLE = 5017; /* list end */
const int RTDOTE = 5018; /* dotted pair */
const int RTNIL = 5019; /* nil */
const int RTDXF0 = 5020; /* DXF code 0 for ads_buildlist only */
const int RTT = 5021; /* T atom */
const int RTRESBUF = 5023; /* resbuf */
const int RTMODELESS = 5027; /* interrupted by modeless dialog */

// Error return code
const int RTNORM = 5100; /* Request succeeded */
const int RTERROR = -5001; // Some other error
const int RTCAN = -5002; // User cancelled request -- Ctl-C
const int RTREJ = -5003; // AutoCAD rejected request -- invalid
const int RTFAIL = -5004; // Link failure -- Lisp probably died
const int RTKWORD = -5005; // Keyword returned from getxxx() routine
const int RTINPUTTRUNCATED = -5008; // Input didn't all fit in the buffer


[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
// For AutoCAD 2007: CharSet = CharSet.Unicode
// [DllImport("acad.exe", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
extern static private int acedGetSym(string args, out IntPtr result);
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
// For AutoCAD 2007: CharSet = CharSet.Unicode
// [DllImport("acad.exe", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
extern static private int acedPutSym(string args, IntPtr result);

//-----------------------------------------------------------------
// AcadGetSym
// --------------
// Fuction get value of lisp-variable
// varname - name of variable
// stat - return code
// Return: ResultBuffer
//-----------------------------------------------------------------
static public ResultBuffer AcadGetSym(string varname,ref int stat)
{
IntPtr rb = IntPtr.Zero;
stat = acedGetSym(varname, out rb);
if (stat == (int)PromptStatus.OK && rb != IntPtr.Zero)
return (ResultBuffer) DisposableWrapper.Create(typeof(ResultBuffer), rb, true);
return null;
}

//-----------------------------------------------------------------
// AcadPutSym
// --------------
// Function put new value to lisp-variable
// varname - name of variable
// rb - ResultBufer
// Return: RTNORM - if all right
//-----------------------------------------------------------------
static public int AcadPutSym(string varname, ResultBuffer rb)
{
return acedPutSym(varname, rb.UnmanagedObject);
}

//
// Test command for geting value of lisp-variable and print it value
//
[CommandMethod("GetSym")]
static public void GetSym()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
int stat = 0;
PromptResult res = ed.GetString("\nName of lisp-variable: ");
if (res.Status == PromptStatus.OK)
{
ResultBuffer args = AcadGetSym(res.StringResult,ref stat) ;
if (args != null)
{
StringBuilder s = new StringBuilder();
s.Append("\n-----------------------------");
foreach (TypedValue val in (IEnumerable) args)
{
s.AppendFormat("\n{0} -> {1}", val.TypeCode, val.Value.ToString());
}
s.Append("\n-----------------------------");
ed.WriteMessage(s.ToString());
}
}
}
//
// Test command for setting value of lisp-variable
//
[CommandMethod("PutSym")]
static public void PutSym()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
PromptResult res = ed.GetString("\nName of lisp-variable: ");
if (res.Status == PromptStatus.OK)
{
ResultBuffer args = new ResultBuffer();
//
// If I add RTLB and RTLE in AutoCAD 2007 - all right, in AutoCAD 2006
// value of lisp-varible is nil
//
// args.Add(new TypedValue(RTLB,-1));
args.Add(new TypedValue(RTSTR,"New String"));
// args.Add(new TypedValue(RTLE,-1));
AcadPutSym(res.StringResult,args) ;
}
}
}
}
[/code]

My question is:
Why in AutoCAD 2006 I can not get/put lisp-variables which is list of atoms (e.g. (= (type var) 'LIST)?
In AutoCAD 2007 I have not problem with this kind of variables.
5 REPLIES 5
Message 2 of 6
Anonymous
in reply to: Anonymous

It seems every time I bring up lisp interaction with dialogs, Tony T says its not possible. Remember the No, No, No
response of the 4/19/2006 thread I started.
I dont doubt that your comments are technically correct, Tony, but I keep seeing more and more lisp communication
routines and now the new attribute in 2007 for doing lisp functions.

It seems at this point, I could at least create a lisp function using .net, that would take params, show a dialog, and
return params. That is a start. Its a little better than using com to communicate with .net since I don't have to
convert variable types.

A .net dialog could also fire lisp functions through the command line, but I thought someone said those functions could
not call the Command lisp function or you get problems. So thats not too great, but I could get around this by closing
the dialog, running the lisp, then reopening. I'm sure Tony is laughing by now, its not ideal I know.

The only thing remaining is how to modify a dialogs controls from lisp. That again could be handled by closing the
dialog and reopening it with desired params. Thats getting rediculous, I know, but there is value in trying to allow
use of existing work done in lisp.

I am not avoiding learning .net, I am simply trying to learn to mix things. Just like I have to mix lisp and dlls from
VB to do what I want many times. I did finally realize I need to read the arx documentation to understand the .net API.
I am walking through the sdk help file of the arx basics. I love new styles of doing things, so its fun. I love making
actual working programs even more though, so I have to get started and set up my library of functions for .net.

One thing I am seeing, is that .net (and arx) has so many lines of code for simple stuff, but its the same pattern over
and over. I am going to set up a library that crunches things down so I have a set of "UFUNS" - remember those from the
old "Maximizing AutoLisp" for R12?
It seems to do that, I should have one param be the transaction object, since constantly making a new one inside each
subroutine is high overhead as I hear.
Anyone got a library going they could share a few examples from?
I am looking for structure type info, like what params do you always pass in (like the trans object) and other patterns.
Then I can stop the lisp comments 🙂

I bet someone could make their website awefully popular by having such a library. Like the Menzi lisp page...
thanks

Alexander Rivilis <>
|>Hello, All!
|>I've wrote a class, which can be helpful in .NET for getting/puttings value of lisp-variables:
|>
|>[code]
|>using System;
|>using System.Runtime.InteropServices;
|>using System.Text;
|>using System.Collections;
|>using Autodesk.AutoCAD.Runtime;
|>using Autodesk.AutoCAD.Geometry;
|>using Autodesk.AutoCAD.ApplicationServices;
|>using Autodesk.AutoCAD.DatabaseServices;
|>using Autodesk.AutoCAD.EditorInput;
|>
|>[assembly: CommandClass(typeof(Rivilis.AcadLispSym))]
|>
|>namespace Rivilis
|>{
|> public class AcadLispSym
|> {
|> //
|> // From adscodes.h :
|> //
|> // Type of resbuf element
|> const int RTNONE = 5000; /* No result */
|> const int RTREAL = 5001; /* Real number */
|> const int RTPOINT = 5002; /* 2D point X and Y only */
|> const int RTSHORT = 5003; /* Short integer */
|> const int RTANG = 5004; /* Angle */
|> const int RTSTR = 5005; /* String */
|> const int RTENAME = 5006; /* Entity name */
|> const int RTPICKS = 5007; /* Pick set */
|> const int RTORINT = 5008; /* Orientation */
|> const int RT3DPOINT = 5009; /* 3D point - X, Y, and Z */
|> const int RTLONG = 5010; /* Long integer */
|> const int RTVOID = 5014; /* Blank symbol */
|> const int RTLB = 5016; /* list begin */
|> const int RTLE = 5017; /* list end */
|> const int RTDOTE = 5018; /* dotted pair */
|> const int RTNIL = 5019; /* nil */
|> const int RTDXF0 = 5020; /* DXF code 0 for ads_buildlist only */
|> const int RTT = 5021; /* T atom */
|> const int RTRESBUF = 5023; /* resbuf */
|> const int RTMODELESS = 5027; /* interrupted by modeless dialog */
|>
|> // Error return code
|> const int RTNORM = 5100; /* Request succeeded */
|> const int RTERROR = -5001; // Some other error
|> const int RTCAN = -5002; // User cancelled request -- Ctl-C
|> const int RTREJ = -5003; // AutoCAD rejected request -- invalid
|> const int RTFAIL = -5004; // Link failure -- Lisp probably died
|> const int RTKWORD = -5005; // Keyword returned from getxxx() routine
|> const int RTINPUTTRUNCATED = -5008; // Input didn't all fit in the buffer
|>
|>
|> [System.Security.SuppressUnmanagedCodeSecurity]
|> [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
|>// For AutoCAD 2007: CharSet = CharSet.Unicode
|>// [DllImport("acad.exe", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|> extern static private int acedGetSym(string args, out IntPtr result);
|> [System.Security.SuppressUnmanagedCodeSecurity]
|> [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
|>// For AutoCAD 2007: CharSet = CharSet.Unicode
|>// [DllImport("acad.exe", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|> extern static private int acedPutSym(string args, IntPtr result);
|>
|> //-----------------------------------------------------------------
|> // AcadGetSym
|> // --------------
|> // Fuction get value of lisp-variable
|> // varname - name of variable
|> // stat - return code
|> // Return: ResultBuffer
|> //-----------------------------------------------------------------
|> static public ResultBuffer AcadGetSym(string varname,ref int stat)
|> {
|> IntPtr rb = IntPtr.Zero;
|> stat = acedGetSym(varname, out rb);
|> if (stat == (int)PromptStatus.OK && rb != IntPtr.Zero)
|> return (ResultBuffer) DisposableWrapper.Create(typeof(ResultBuffer), rb, true);
|> return null;
|> }
|>
|> //-----------------------------------------------------------------
|> // AcadPutSym
|> // --------------
|> // Function put new value to lisp-variable
|> // varname - name of variable
|> // rb - ResultBufer
|> // Return: RTNORM - if all right
|> //-----------------------------------------------------------------
|> static public int AcadPutSym(string varname, ResultBuffer rb)
|> {
|> return acedPutSym(varname, rb.UnmanagedObject);
|> }
|>
|> //
|> // Test command for geting value of lisp-variable and print it value
|> //
|> [CommandMethod("GetSym")]
|> static public void GetSym()
|> {
|> Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
|> int stat = 0;
|> PromptResult res = ed.GetString("\nName of lisp-variable: ");
|> if (res.Status == PromptStatus.OK)
|> {
|> ResultBuffer args = AcadGetSym(res.StringResult,ref stat) ;
|> if (args != null)
|> {
|> StringBuilder s = new StringBuilder();
|> s.Append("\n-----------------------------");
|> foreach (TypedValue val in (IEnumerable) args)
|> {
|> s.AppendFormat("\n{0} -> {1}", val.TypeCode, val.Value.ToString());
|> }
|> s.Append("\n-----------------------------");
|> ed.WriteMessage(s.ToString());
|> }
|> }
|> }
|> //
|> // Test command for setting value of lisp-variable
|> //
|> [CommandMethod("PutSym")]
|> static public void PutSym()
|> {
|> Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
|> PromptResult res = ed.GetString("\nName of lisp-variable: ");
|> if (res.Status == PromptStatus.OK)
|> {
|> ResultBuffer args = new ResultBuffer();
|>//
|>// If I add RTLB and RTLE in AutoCAD 2007 - all right, in AutoCAD 2006
|>// value of lisp-varible is nil
|>//
|>// args.Add(new TypedValue(RTLB,-1));
|> args.Add(new TypedValue(RTSTR,"New String"));
|>// args.Add(new TypedValue(RTLE,-1));
|> AcadPutSym(res.StringResult,args) ;
|> }
|> }
|> }
|>}
|>[/code]
|>
|>My question is:
|>Why in AutoCAD 2006 I can not get/put lisp-variables which is list of atoms (e.g. (= (type var) 'LIST)?
|>In AutoCAD 2007 I have not problem with this kind of variables.
James Maeding
Civil Engineer and Programmer
jmaeding - athunsaker - com
Message 3 of 6
odurier
in reply to: Anonymous

I have test this code under AutoCAd Architecture 2011 and it doesn't work

 

I have set a variable

(setq a "test")

and i have run getsym command

the first time the value is null

the second time the value is good "test"

 

I have set a other variable (two caracters)

(setq aa "test")

and i have run getsym command

the first time the value is null

the second time the value is null

Never the value is returned

 

SOMEONE HAVE AN IDEA?

 

[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
extern static private int acedGetSym(string name, out IntPtr result);

internal static ResultBuffer GetLispSym(string name)
{
IntPtr ip = IntPtr.Zero;
acedGetSym(name, out ip);
if (ip != IntPtr.Zero)
{
ResultBuffer rbRes = ResultBuffer.Create(ip, true);
return rbRes;
}
return null;
}
#endregion


[CommandMethod("GetSym")]
static public void GetSym()
{
Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;

 

int stat = 0;
PromptResult res = ed.GetString("Name of lisp-variable: ");
if (res.Status == PromptStatus.OK)
{
ResultBuffer args = GetLispSym(res.StringResult);
if (args != null)
{
foreach (TypedValue val in args)
{
 MessageBox.Show(val.Value.ToString());
}

}
}
}

Message 4 of 6
phoinix
in reply to: Anonymous

I am loading the AutoCAD2011 today to test the version

of the acedGetSym package invoke routine that I have.

I want to see if I get the same behavior that you are seeing.

If my version works OK... I will post it for you.

 

Did you test yours on AutoCAD2010?

What happened then?

 

Message 5 of 6
odurier
in reply to: Anonymous

After 2 hours of tests i have found the solution

The problem was in the dllimport synthax

I have add "CharSet = CharSet.Unicode"

It work fine now

Thanks

[

 

DllImport("acad.exe", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedGetSym")

]

 

Message 6 of 6
phoinix
in reply to: Anonymous

I had a suspicion that was the problem when reviewing your code.

 

I think Autodesk changed to Unicode after 2007.

 

Kean mentioned that in his through the interface blaug.

 

OK it sounds like you are good to go.

 

P

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