Is anyone using (or know of code which uses) Lispworks in a situation
where you have to pass /to/ a C function a reference to a Lisp function
(defined by define-foreign-callable) to be called by the C library at
some later time?
ACL offers ff:register-foreign-callable, which returns several values,
the first of which can be passed to a C function for later use as a
callback.
LW's define-foreign-callable returns just the string name of the
function defined. I doubted FUNCTION would work, and anyway d-f-c does
not create anything FUNCTIOn could work off.
Unfortunately the LW example shows how it first defines XXX, a lisp
function callable from C, but then they get cute and define this "XXX" c
function to be called from Lisp, so when they call the C XXX they end up
back in the Lisp XXX. Cute, but it leaves the question of how to
identify the callback to a C library.
I am starting to think it is time to cut my losses and modify FreeGlut
to support a get-next-event approach to message/event handling. A
one-time effort, then UFFI is my savior.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
the bath water is cold." -- Lorraine Lee Cudmore
Kenny Tilton <·······@nyc.rr.com> wrote in message news:<················@nyc.rr.com>...
> Is anyone using (or know of code which uses) Lispworks in a situation
> where you have to pass /to/ a C function a reference to a Lisp function
> (defined by define-foreign-callable) to be called by the C library at
> some later time?
Anything that uses the expat XML library will do this at some level.
There are free expat bindings for LW and ACL, which I have somewhat
modified copies of
(mostly my modifications were better searching for the expat library,
and
stuff to make it work on Windows where encodings matter more).
I don't have a URL for the public versions (or my modified ones) here,
but I can send you them next week when I'm back home. Mail me if
you're interested.
The expat stuff is somewhat obscure since it has a layer which
isolates the LW/ACL specific parts, but in general I think it's not
that hard.
--tim
Sample code at:
http://www.jeffcaldwell.com/article.pl?sid=03/01/03/2342225&mode=thread
Follow the link back to the home page, there's a more recent article
that details a little of the progress I've made since then.
Jeff
Kenny Tilton wrote:
> Is anyone using (or know of code which uses) Lispworks in a situation
> where you have to pass /to/ a C function a reference to a Lisp function
> (defined by define-foreign-callable) to be called by the C library at
> some later time?
>
> ACL offers ff:register-foreign-callable, which returns several values,
> the first of which can be passed to a C function for later use as a
> callback.
>
> LW's define-foreign-callable returns just the string name of the
> function defined. I doubted FUNCTION would work, and anyway d-f-c does
> not create anything FUNCTIOn could work off.
>
> Unfortunately the LW example shows how it first defines XXX, a lisp
> function callable from C, but then they get cute and define this "XXX" c
> function to be called from Lisp, so when they call the C XXX they end up
> back in the Lisp XXX. Cute, but it leaves the question of how to
> identify the callback to a C library.
>
> I am starting to think it is time to cut my losses and modify FreeGlut
> to support a get-next-event approach to message/event handling. A
> one-time effort, then UFFI is my savior.
>
>
Jeff Caldwell wrote:
>
> Sample code at:
>
> http://www.jeffcaldwell.com/article.pl?sid=03/01/03/2342225&mode=thread
ah, there it is, buried in the discussion of make-pointer, but pretty
well laid out. How did you figure out you had to pass the
pointer-address of the make-pointer result? It sounds as if make-pointer
on the callback would give the necessary callback address, but obviously
not based on your code. Go figger.
Thx much, I'll give it a try.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
the bath water is cold." -- Lorraine Lee Cudmore
I had asked for help on ········@xanalys.com and Marc Battyani responded
with a hint about the API. Dave Tarvydas responded with Lisp and C code
to drive the message loop from a C DLL. The example in the link is
Lisp/fli only, however.
I think you can set up the fli C structs to automatically coerce the
pointers but that was yet another layer of fli-fighting which I avoided
by typing the C pointers as unsigned longs and calling pointer-address
manually. ymmv.
Jeff
Kenny Tilton wrote:
> ah, there it is, buried in the discussion of make-pointer, but pretty
> well laid out. How did you figure out you had to pass the
> pointer-address of the make-pointer result? It sounds as if make-pointer
> on the callback would give the necessary callback address, but obviously
> not based on your code. Go figger.
>
> Thx much, I'll give it a try.
>
>
>
Kenny Tilton <·······@nyc.rr.com> writes:
> ah, there it is, buried in the discussion of make-pointer, but pretty
> well laid out. How did you figure out you had to pass the
> pointer-address of the make-pointer result? It sounds as if
> make-pointer on the callback would give the necessary callback
> address, but obviously not based on your code. Go figger.
One more thing; this may be obvious (or it may not) --- you have
to make sure that C calls the lisp function under the control
of Lisp, i.e. not totally asynchronously, from a C thread (say).
If that didn't parse, let me know, and I'll answer at greater
length and clarity.
Alain Picard <·······················@optushome.com.au> writes:
> One more thing; this may be obvious (or it may not) --- you have to
> make sure that C calls the lisp function under the control of Lisp,
> i.e. not totally asynchronously, from a C thread (say).
>
> If that didn't parse, let me know, and I'll answer at greater length
> and clarity.
Uh, it didn't parse for me at least, so if you could find some time to
add more details I'd be glad.
Thanks in advance,
Edi.
Edi Weitz wrote:
> Alain Picard <·······················@optushome.com.au> writes:
>
>
>>One more thing; this may be obvious (or it may not) --- you have to
>>make sure that C calls the lisp function under the control of Lisp,
>>i.e. not totally asynchronously, from a C thread (say).
>>
>>If that didn't parse, let me know, and I'll answer at greater length
>>and clarity.
>
>
> Uh, it didn't parse for me at least, so if you could find some time to
> add more details I'd be glad.
My wild stab at it is that I am OK, because I (in Lisp) call C functions
in the Glut DLL, which then calls back the functions pointers to which I
earlier passed to Glut.
I gather also that I could still be in trouble if Glut kicked off a
thread from which callbacks would be made, but I have not noticed
anything like that in mucho perusal of Glut source.
fwiw.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
the bath water is cold." -- Lorraine Lee Cudmore
Kenny Tilton <·······@nyc.rr.com> writes:
>
> I gather also that I could still be in trouble if Glut kicked off a
> thread from which callbacks would be made, but I have not noticed
> anything like that in mucho perusal of Glut source.
>
Hopefully someone more LispWorks savy will jump in if I'm wrong, but
from what I gather LispWorks isn't multiprocessing-safe at all, so it
doesn't necessarily have to be from a different thread. Any time you
have more then one chunk of Lisp code executing "at the same time" it
could be unsafe. For example, if you installed a callback for a
button and maintained the Lisp event loop outside of Glut you could be
in dangerous territory.
Gabe Garza
Gabe Garza <·······@ix.netcom.com> writes:
> Kenny Tilton <·······@nyc.rr.com> writes:
>
> > I gather also that I could still be in trouble if Glut kicked off
> > a thread from which callbacks would be made, but I have not
> > noticed anything like that in mucho perusal of Glut source.
>
> Hopefully someone more LispWorks savy will jump in if I'm wrong, but
> from what I gather LispWorks isn't multiprocessing-safe at all, so
> it doesn't necessarily have to be from a different thread. Any time
> you have more then one chunk of Lisp code executing "at the same
> time" it could be unsafe. For example, if you installed a callback
> for a button and maintained the Lisp event loop outside of Glut you
> could be in dangerous territory.
The question is in which context those installed callbacks are called.
If the only way they are called is that a LispWorks light-weight
thread calls GLUT, and then GLUT, in this same context, calls his
callbacks, everything should be fine, as there is only one Unix thread
operating on the code.
Regards,
--
Nils G�sche
"Don't ask for whom the <CTRL-G> tolls."
PGP key ID 0x0655CFA0
Nils Goesche <······@cartan.de> writes:
> Gabe Garza <·······@ix.netcom.com> writes:
>
> The question is in which context those installed callbacks are called.
> If the only way they are called is that a LispWorks light-weight
> thread calls GLUT, and then GLUT, in this same context, calls his
> callbacks, everything should be fine, as there is only one Unix thread
> operating on the code.
I don't know what a "LispWorks light-weight thread" is, but if you're
referring ot a LW "process", then, yes, your analysis is correct, as
far as I understand LW.
I once na�vely tried to get a C thread to asynchronously call LW callbacks,
with random consequences; Xanalys support told me I had to let LW drive
the polling loop to call C to call lisp back "on its own thread".
Hope that helps.
Gabe Garza wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
>
>
>>I gather also that I could still be in trouble if Glut kicked off a
>>thread from which callbacks would be made, but I have not noticed
>>anything like that in mucho perusal of Glut source.
>>
>
>
> Hopefully someone more LispWorks savy will jump in if I'm wrong, but
> from what I gather LispWorks isn't multiprocessing-safe at all, so it
> doesn't necessarily have to be from a different thread. Any time you
> have more then one chunk of Lisp code executing "at the same time" it
> could be unsafe. For example, if you installed a callback for a
> button and maintained the Lisp event loop outside of Glut you could be
> in dangerous territory.
Good point. I get much diff behavior when I insert a sleep in the
otherwise tight loop calling glut to handle the next event. I guess then
that if I do anything in a callback such as break, look out.
We'll see, but thx for the input, I'll keep this in mind if LW does not
like my shenanigans.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
the bath water is cold." -- Lorraine Lee Cudmore
Jeff Caldwell <·····@yahoo.com> wrote in message news:<················@yahoo.com>...
> Sample code at:
>
> http://www.jeffcaldwell.com/article.pl?sid=03/01/03/2342225&mode=thread
>
> Follow the link back to the home page, there's a more recent article
> that details a little of the progress I've made since then.
In the credit-where-due department, thought I'd swing by this old
thread to say thanks, that did the trick. Here is what I have now on
callbacks:
(defun ff-register-callable (callback-name)
#+allegro
(ff:register-foreign-callable callback-name)
#+lispworks
(fli:pointer-address
(fli:make-pointer :symbol-name (symbol-name callback-name)
:functionp t)))
[the above needs a new name, it just got swept over from the ACL
nomenclature]
(defmacro ff-defun-callable (result-type name args &body body)
(declare (ignorable result-type))
#+lispworks
`(fli:define-foreign-callable (,(symbol-name name) :result-type
,result-type)
(,@args)
,@body)
#+allegro
`(ff:defun-foreign-callable ,name ,args
,@body))
BTW, at one point I asked "why call pointer-address?", but when i
slowed down I saw that make-pointer output does indeed need to be
un-boxed to get at the callable address. my bad.
kenny
clinisys