An FYI and a question:
I am trying to call C code generated by lex/yacc from Allegro CL.
After rooting around in the documentation, I found how to do this
easily. It can be done with the following code:
(load "foo.o")
(ff:defforeign 'foo
:entry-point "_foo"
:arguments '(string)
:return-type :integer)
Where "foo.o" is the object code produced from the C file, foo.c.
Defforeign defines a function (symbol) named foo. The entry-
point is the name of the function in the object code. (C prepends an
underscore.) Arguments is an ordered list of the input parameter
types. Return-type is return type.
The C function can then be called as a normal Lisp function:
(foo "bar") => 123
The problem - I need to be able to return a string. Unfortunately,
:string is not one of the legal choices for :return-type, although is
is a legal type for arguments. Does any one know of a work around?
One possibility is to return an address then some how coerce it into a
string. Another possibility is to store the string in global memory
then have Lisp access it some how. I have tried this with
lispvalue(), but Load complains about not being able to finding it.
Any help or pointers would be very much appreciated.
Mark
From: Mark S McWhinney
Subject: Re: Allegro CL and C code
Date:
Message-ID: <BvD364.CAs.2@cs.cmu.edu>
FYI -
Nick (ยทยทยทยท@cs.washington.edu) sent the following answer which I have
tested. I works great.
Here's what I did when I wanted to pass AND get back a string.
The key is to have a :fixnum get returned, and then use
ff:char*-to-string.
(ff:defforeign 'espresso-interface
:arguments '(string)
:return-type :fixnum
:entry-point *espresso-interface-entry-point*)
and the function call
(ff:char*-to-string (espresso-interface <argument>))