[Ecls-list] Problems with updating an external global variable

Dietrich Bollmann dietrich at formgames.org
Wed Jul 17 09:33:07 UTC 2013


Hi Juanjo,

Sorry for being unclear.

I am writing a plugin for Rhino3D, a NURBS-based 3-D modeling software.
 The plugin makes it possible to script RhinoNURBS models with lisp.

When the plugin is used, the following function is called by Rhino:

---

  CRhinoCommand::result CCommandRhinoLisp::RunCommand(const
CRhinoCommandContext& context) {
    ...
  }

---

The parameter 'context' (for which I unsuccessfully substituted
'global_int' in my last email to make things "easier to understand"...) is
essential for many of the Rhino functions.  The following, for example,
adds a cone object (which has to be initialized before) to a Rhino scene:

---

  context.m_doc.AddObject(cone_object);

---

I therefore need a way to access 'context' from lisp and thought about
implementing this via a global variable which is set in the RunCommand()
function.  But for some reason I was not able to overwrite the value of the
global variable...

Currently I therefore solve the problem as follows:

In the file where the lisp wrappers are defined I have the following:

--- rhino-lisp-api.lisp ---

(ffi:clines "static CRhinoCommandContext *global_rhinoCommandContext = (
CRhinoCommandContext *) NULL;")

(defun set-rhino-command-context (context)
  (ffi:c-inline
   (context) (:pointer-void) :void
   "global_rhinoCommandContext = (CRhinoCommandContext *) #0"
   :one-liner t
   :side-effects t))

(defun get-rhino-command-context ()
  (ffi:c-inline
   () () :pointer-void
   "(void *) global_rhinoCommandContext"
   :one-liner t
   :side-effects t))

---

>From RunCommand() I call the function setRhinoCommandContext(context) and
define the constant '+context+' to refer to the Rhino command context:

---

CRhinoCommand::result CCommandRhinoLisp::RunCommand(const
CRhinoCommandContext& context) {

  ...

  setRhinoCommandContext(context);

  cl_eval(READCL((defconstant +context+ (get-rhino-command-context)
  "The Rhino Command Context")));
  ...
}

---

setRhinoCommandContext() is defined as follows:

---

static void setRhinoCommandContext(const CRhinoCommandContext& context) {

  union cl_lispunion cl_context_object;
  cl_context_object.foreign.t    = t_foreign;
  cl_context_object.foreign.tag  = ECL_SYM(":POINTER-VOID",1377);
  cl_context_object.foreign.size = 0;
  cl_context_object.foreign.data = (char*) &context;
  cl_object cl_context = &cl_context_object;

  cl_funcall(2, c_string_to_object("set-rhino-command-context"),
cl_context);
}

---

It works, but I wonder if there is a better way to solve this problem?

Rather than wrapping the pointer into a cl_object it would be nice to
directly define the setter function in the file where the lisp wrappers are
defined:

--- rhino-lisp-api.lisp ---

(ffi:clines "

static CRhinoCommandContext *global_rhinoCommandContext = (
CRhinoCommandContext *) NULL;

static void setRhinoCommandContext(const CRhinoCommandContext &context) {
  global_rhinoCommandContext = (CRhinoCommandContext *) &context;
}

")

(defun get-rhino-command-context ()
  (ffi:c-inline
   () () :pointer-void
   "(void *) global_rhinoCommandContext"
   :one-liner t
   :side-effects t))

---

At least I would like to avoid hardcoding the integer 1377 corresponding to
":POINTER-VOID" - for example by using some (imagined) function
'pointer_to_cl_object()':

---

static void setRhinoCommandContext(const CRhinoCommandContext& context) {

  cl_funcall(2,
             c_string_to_object("set-rhino-command-context"),
             pointer_to_cl_object((char*) &context));
}

---

But I was not able to find anything similar...

Is my explanation more understandable this time?

Thanks, Dietrich


On Sun, Jul 14, 2013 at 3:21 AM, Juan Jose Garcia-Ripoll <
juanjose.garciaripoll at gmail.com> wrote:

>
> On Sat, Jul 13, 2013 at 5:31 PM, Dietrich Bollmann <dietrich at formgames.org
> > wrote:
>
>> But when evaluating (test) before and after the value is changed, in both
>> cases the original value is printed
>
>
> You cooked up a very nice and complex example and leave out the most
> relevant part which is where you use the lisp code. How does this code look
> like?
>
>
> --
> Instituto de Física Fundamental, CSIC
> c/ Serrano, 113b, Madrid 28006 (Spain)
> http://juanjose.garciaripoll.googlepages.com
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/ecl-devel/attachments/20130717/c887145f/attachment.html>


More information about the ecl-devel mailing list