Author Topic: Set Lisp variable with .net?  (Read 4878 times)

0 Members and 1 Guest are viewing this topic.

jmaeding

  • Bull Frog
  • Posts: 304
  • I'm just here for the Shelties.
Set Lisp variable with .net?
« on: March 21, 2008, 06:36:55 PM »
I have some rather large lisp programs that set global variables for certain things.
I do compile my progs to vlx and use separate namespaces, so the globals are only visible to the vlx.
I could have sworn I ran accross this before, but cannot seem to find the answer.
Can .net read and set the value of a lisp variable?  The same as if I did (setq TestVar "somestring") in lisp?
Can it do that for a namespace too?

I'm guessing its a matter of getting or sending a resultbuffer from/to the document object somehow.
Any help appreciated.
James Maeding

jmaeding

  • Bull Frog
  • Posts: 304
  • I'm just here for the Shelties.
Re: Set Lisp variable with .net?
« Reply #1 on: March 21, 2008, 06:51:31 PM »
ah, finally found it - the acedgetsym and putsym methods...
James Maeding

tjr

  • Guest
Re: Set Lisp variable with .net?
« Reply #2 on: March 21, 2008, 06:52:07 PM »
See this.

jmaeding

  • Bull Frog
  • Posts: 304
  • I'm just here for the Shelties.
Re: Set Lisp variable with .net?
« Reply #3 on: March 23, 2008, 12:13:50 AM »
ah, good link.
I noticed people commenting that its ugly doing complex progs in lisp.
I have done very complex progs in lisp, and have no problem keeping track of things.
The key is to come up with a system of handling global variables for forms and general program settings.
I also use OpenDcl, not dcl.
The VB and .net IDE's are sure nice compared to the VLIDE though.
James Maeding

jmaeding

  • Bull Frog
  • Posts: 304
  • I'm just here for the Shelties.
Re: Set Lisp variable with .net?
« Reply #4 on: March 24, 2008, 08:14:59 PM »
Ok, after reading around and trying things, I am having pretty good success with the things involving resultbuffers.
The only thing not working is setting a var with a list of vals.
This works (code from Daniel):
Code: [Select]
static public bool PutSym(string variableName, object value)
    {

      bool flag;
      ResultBuffer val = new ResultBuffer();
      try
      {
        val.Add(new TypedValue(RTSTR, value));
        if (acedPutSym(variableName, val.UnmanagedObject) == RTNORM)
        {
          return true;
        }
        flag = false;
      }
      catch
      {
        throw;
      }
      finally
      {
        val.Dispose();
      }
      return flag;
    }

now if I duplicate the line a few times:
Code: [Select]
val.Add(new TypedValue(valType, value));
val.Add(new TypedValue(valType, value));
val.Add(new TypedValue(valType, value));

to further populate the resbuff, it does not work, I get a -5001 error.
Do I need to add a "list begin" and "list end" item in?
I thought that was only if I wanted to do nested lists.

I'm on acad 2008...thx
James Maeding

jmaeding

  • Bull Frog
  • Posts: 304
  • I'm just here for the Shelties.
Re: Set Lisp variable with .net?
« Reply #5 on: March 24, 2008, 08:24:55 PM »
whoohoo! the trick is to add list begin and end group:
            rb.Add(new TypedValue((int)RTLB, ""));
            rb.Add(new TypedValue((int)RTSTR, "wowsers"));
            rb.Add(new TypedValue((int)RTSTR, "wowsers4"));
            rb.Add(new TypedValue((int)RTSTR, "wowsers2"));
            rb.Add(new TypedValue((int)RTLE, ""));

result on command line is:
Command: !james3
("wowsers" "wowsers4" "wowsers2")
not that surprising really.

Now, I believe the getSym returns a resbuff without the list begin and end groups, unless its a nested list.
I just thought the reverse would be true, no need to wrap in a list, a resbuff is a list by default in this context.
I've seen like 20 examples doing lots of things with resbuffs, but no one ever set a var using a list, they were always feeding them into some other item than AcedPutSym.
thx
James Maeding

jmaeding

  • Bull Frog
  • Posts: 304
  • I'm just here for the Shelties.
Re: Set Lisp variable with .net?
« Reply #6 on: March 24, 2008, 08:53:04 PM »
nope, the begin and end list was mentioned before in:
http://www.theswamp.org/index.php?topic=11921.0

funny how you notice things after the fact...
James Maeding

jmaeding

  • Bull Frog
  • Posts: 304
  • I'm just here for the Shelties.
Re: Set Lisp variable with .net?
« Reply #7 on: March 24, 2008, 08:55:25 PM »
Now to read and write vars in a var part of a separate namespace.
I have not seen anything on that.
I'll look over the arx docs...
James Maeding

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8728
  • AKA Daniel
Re: Set Lisp variable with .net?
« Reply #8 on: March 24, 2008, 11:59:29 PM »
I've seen like 20 examples doing lots of things with resbuffs, but no one ever set a var using a list, they were always feeding them into some other item than AcedPutSym.

James, 
Most of the examples here use the LispFunction attribute to interop with lisp, ie

Code: [Select]

//(setq w00t (doit "caution"))
    [LispFunction("doit")]
    public static Object doit(ResultBuffer buff)
    {
      //turn the ResultBuffer into a list to make it easier to work
      List<TypedValue> lispLisp = new List<TypedValue>(buff.AsArray());

      //Initialize our return buffer
      ResultBuffer rb = new ResultBuffer();

      string str = string.Empty;

      //since the return type is Object. we can return a string here
      if (lispLisp.Count == 0)
        return "Error of type PEBUAK";

      //test the first value of the list to see if it is a string
      if (lispLisp[0].TypeCode == (int)LispDataType.Text)
      {
        //get the string (value is boxed as an Object so we need to cast)
        str = lispLisp[0].Value as string;

        //start a new list
        rb.Add(new TypedValue((int)LispDataType.ListBegin));

        foreach (char chr in str.ToCharArray())
        {
          rb.Add(new TypedValue((int)LispDataType.ListBegin));//start of cons list
          rb.Add(new TypedValue((int)LispDataType.Text, new string(new char[] { chr })));
          rb.Add(new TypedValue((int)LispDataType.DottedPair)); //dot
          rb.Add(new TypedValue((int)LispDataType.Int16, chr));
          rb.Add(new TypedValue((int)LispDataType.ListEnd));//end of cons list
        }
        //close the list
        rb.Add(new TypedValue((int)LispDataType.ListEnd));
      }

      //since the return type is Object. we can return a ResultBuffer
      return rb;
    }


jmaeding

  • Bull Frog
  • Posts: 304
  • I'm just here for the Shelties.
Re: Set Lisp variable with .net?
« Reply #9 on: March 25, 2008, 11:54:15 AM »
Thanks, the more examples the better.
In lisp, I use (vl-doc-ref 'somevar) to read a var in a spearate namespace.
I think I have the tools now to deal with that.  Worst case, i could make a lisp function that .net calls, then sends back to .net.
Its funny because i asked about this kind of stuff a long time ago, and no one knew how then.
Thanks a bunch for sharing your hard fought know-how.
James Maeding

jmaeding

  • Bull Frog
  • Posts: 304
  • I'm just here for the Shelties.
Re: Set Lisp variable with .net?
« Reply #10 on: March 25, 2008, 01:44:33 PM »
hmm, seems I cannot access a separate namespace lisp var no matter what I try.
Just with lisp, the (vl-doc-ref...) will not let you access a var created from a vlx.
I compile all my progs to vlx with separate namespaces.
I might need to include a function in each prog, that exposes a variable within the prog's namespace.
I'll try that...
James Maeding

jmaeding

  • Bull Frog
  • Posts: 304
  • I'm just here for the Shelties.
Re: Set Lisp variable with .net?
« Reply #11 on: March 25, 2008, 06:44:14 PM »
ok, simple solution is to add a function to my lisp prog, exposing a given variable:
(defun ct-getgvar (gvar / )
   (eval (read gvar))
)

then export it so things outside the vlx namespace can run the function:
(vl-doc-export 'ct-getgvar)

Then I can call (CT-GetGVAR "CT-PTBAR-GVAR") on the command line to test, or with .net for real use to see the variable normally hidden within the vlx namespace.

I need to do a CT-SetGVAR too, to allow write as well as read.
The trick is the fact that the CT-GetGVAR function takes a string argument.
You can feed it any var name you want to get at, assuming you know the names :)
Also, each lisp app should have a different "GetGVAR" and "SetGvar" name so you don't get confused on which app you are grabbing vars from.
fun stuff.
James Maeding

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8728
  • AKA Daniel
Re: Set Lisp variable with .net?
« Reply #12 on: March 26, 2008, 02:20:24 AM »
You lost me somewhere, why couldn’t you just make the call to the .NET lisp method to update the global
i.e

Code: [Select]
(DEFUN UPDATEGLOBALVARA ()
 (SETQ GLOBALVARA (DOTNETFUNC))
)

jmaeding

  • Bull Frog
  • Posts: 304
  • I'm just here for the Shelties.
Re: Set Lisp variable with .net?
« Reply #13 on: March 26, 2008, 01:57:10 PM »
It makes more sense if you understand the sequence I am trying to do:
1) a vlx app sets 5 global vars
2) a .net command accesses them, does somthing, and possibly updates them

The .net command will not be defined with Lispfunction attribute, only as a command.

you see, no one has ever mentioned how .net accesses a global lisp var set via a separate namespace vlx.
I am saying you have to add a function to your vlx app to do so.  Make the function flexible so it takes a string argument, and returns the value of the var by that name.

I don't want the lisp app to be aware of the .net command running.  It might discover that its vars have changed at a later time, but it has no idea of what changed them.
I think your suggestion was saying to have lisp initiate the .net command, which is a bit different than I am doing.

In the future, I will replace my larger lisp apps completely with .net, so there will be a point in time where I tell my .net functions to grab settings from .net, not from lisp vars.
Thanks for sticking with this so far.
James Maeding