A toy example of embedding C code in lisp and vice versa

B

bolega

Here is a link to a thread that discusses this topic but there is no
complete example.

http://objectmix.com/lisp/362409-howto-use-lisp-scripting-language-within-c.html

Lars Lune has a good section on code by searching this string

"On Tue, 18 Mar 2008 01:16:00 -0700, Blackguester wrote:"

but his code is replaced with smileys and even source shows it. I
could not muster the confidence as a newbie to go into it by myself.
Unless a guru can guide and explain.

http://common-lisp.net/project/cffi/
http://common-lisp.net/project/cffi/manual/html_node/Tutorial.html
http://www.sbcl.org/manual/Foreign-Function-Interface.html

Should I pick SBCL or ECL ? I have a long term view.
 
B

bolega

Here is a link to a thread that discusses this topic but there is no
complete example.

http://objectmix.com/lisp/362409-howto-use-lisp-scripting-language-wi...

Lars Lune has a good section on code by searching this string

"On Tue, 18 Mar 2008 01:16:00 -0700, Blackguester wrote:"

but his code is replaced with smileys and even source shows it. I
could not muster the confidence as a newbie to go into it by myself.
Unless a guru can guide and explain.

http://common-lisp.net/project/cffi...cl.org/manual/Foreign-Function-Interface.html

Should I pick SBCL or ECL ? I have a long term view.

http://www.sbcl.org/manual/Calling-Lisp-From-C.html#Calling-Lisp-From-C

8.7.4 Calling Lisp From C

Calling Lisp functions from C is sometimes possible, but is extremely
hackish and poorly supported as of SBCL 0.7.5. See funcall0 ...
funcall3 in the runtime system. The arguments must be valid SBCL
object descriptors (so that e.g. fixnums must be left-shifted by 2.)
As of SBCL 0.7.5, the format of object descriptors is documented only
by the source code and, in parts, by the old CMUCL INTERNALS
documentation.

Note that the garbage collector moves objects, and won't be able to
fix up any references in C variables. There are three mechanisms for
coping with this:

1. The sb-ext:purify moves all live Lisp data into static or read-
only areas such that it will never be moved (or freed) again in the
life of the Lisp session
2. sb-sys:with-pinned-objects is a macro which arranges for some
set of objects to be pinned in memory for the dynamic extent of its
body forms. On ports which use the generational garbage collector (as
of SBCL 0.8.3, only the x86) this has a page granularity - i.e. the
entire 4k page or pages containing the objects will be locked down. On
other ports it is implemented by turning off GC for the duration (so
could be said to have a whole-world granularity).
3. Disable GC, using the without-gcing macro.


[Q] How easy is it to call ECL http://sourceforge.net/projects/ecls/
from C ?

Any toy example of doing this ?

what type of problem set would advise us that we embed C in LISP and
where lisp in C ?

Some toy examples ? send me email if you will share thru private
correspondance only.
 
P

Pascal J. Bourguignon

bolega said:
Here is a link to a thread that discusses this topic but there is no
complete example.

http://objectmix.com/lisp/362409-howto-use-lisp-scripting-language-within-c.html

Lars Lune has a good section on code by searching this string

"On Tue, 18 Mar 2008 01:16:00 -0700, Blackguester wrote:"

but his code is replaced with smileys and even source shows it. I
could not muster the confidence as a newbie to go into it by myself.
Unless a guru can guide and explain.

http://common-lisp.net/project/cffi/
http://common-lisp.net/project/cffi/manual/html_node/Tutorial.html
http://www.sbcl.org/manual/Foreign-Function-Interface.html

Should I pick SBCL or ECL ? I have a long term view.

In the long term, we're all dead.

The point of a STANDARD, is that you can write programs that will work
equally on any implementation.

You are not asking yourself whether in the long term, you should buy
today an Intel or an AMD process. That's because in the long term, it
doesn't matter since they both implement the same stadanrd virtual
machine.

Guess what? It's the same for all the CL implementations: they all
implement the same virtual machine! The portable Common Lisp Virtual
Machine.

So just write your program in portable Common Lisp, and in the long
term they will run on any CL implementation.


Actually, in the long term you could even use some extensions or
divergent Lisp stuff, since it's Lisp, it's easy to write
compatibility layers. For example, here is how you could in the long
term run code written 50 years ago, today in any Common Lisp
implementation:
http://www.informatimago.com/develop/lisp/small-cl-pgms/wang.html

That is, homoiconicity and easy meta-programming is essential to long
term perenity of code.



Now if your problem is to mix C code and Lisp code, the only question
you may have to ask yourself is in what language the entry point will
be written.

If in Lisp, you can use any CL implementation that has FFI (or CFFI
for the portability), and call any C code put in a library.

If in C, then you will have to use ECL, which can be used embedded in
a C program as a C library.

Frankly, this is really a question of no relevance, since you can
always s/int main/extern int my_application_main/ in your C sources
and link it into a library instead of a program, to be loaded in SBCL
or any other CL.



Perhaps you could start to learn a use Common Lisp, so that you would
provide us with more interesting questions?
 
B

bolega

Now if your problem is to mix C code and Lisp code, the only question
you may have to ask yourself is in what language the entry point will
be written.

If in Lisp, you can use any CL implementation that has FFI (or CFFI
for the portability), and call any C code put in a library.

If in C, then you will have to use ECL, which can be used embedded in
a C program as a C library.

Frankly, this is really a question of no relevance, since you can
always s/int main/extern int my_application_main/ in your C sources
and link it into a library instead of a program, to be loaded in SBCL
or any other CL.

Perhaps you could start to learn a use Common Lisp, so that you would
provide us with more interesting questions?

Thats why I was asking for a toy example from someone who has done it.
I can download the programs ECL and Allegro. One toy example of each
paradigm, including the third one of the libraries you mention. Most
likely, it would be including some C/Python library for efficiency and
availability and reuse in Lisp code to avoid rewrite.
 
N

nanothermite911fbibustards

Here is a link to a thread that discusses this topic but there is no
complete example.

http://objectmix.com/lisp/362409-howto-use-lisp-scripting-language-wi...

Lars Lune has a good section on code by searching this string

"On Tue, 18 Mar 2008 01:16:00 -0700, Blackguester wrote:"

but his code is replaced with smileys and even source shows it. I
could not muster the confidence as a newbie to go into it by myself.
Unless a guru can guide and explain.

http://common-lisp.net/project/cffi...cl.org/manual/Foreign-Function-Interface.html

Should I pick SBCL or ECL ? I have a long term view.

8.8 Step-By-Step Example of the Foreign Function Interface

This section presents a complete example of an interface to a somewhat
complicated C function.

Suppose you have the following C function which you want to be able to
call from Lisp in the file test.c

struct c_struct
{
int x;
char *s;
};

struct c_struct *c_function (i, s, r, a)
int i;
char *s;
struct c_struct *r;
int a[10];
{
int j;
struct c_struct *r2;

printf("i = %d\n", i);
printf("s = %s\n", s);
printf("r->x = %d\n", r->x);
printf("r->s = %s\n", r->s);
for (j = 0; j < 10; j++) printf("a[%d] = %d.\n", j, a[j]);
r2 = (struct c_struct *) malloc (sizeof(struct c_struct));
r2->x = i + 5;
r2->s = "a C string";
return(r2);
};

It is possible to call this C function from Lisp using the file
test.lisp containing

(cl:defpackage "TEST-C-CALL" :)use "CL" "SB-ALIEN" "SB-C-CALL"))
(cl:in-package "TEST-C-CALL")

;;; Define the record C-STRUCT in Lisp.
(define-alien-type nil
(struct c-struct
(x int)
(s c-string)))

;;; Define the Lisp function interface to the C routine. It
returns a
;;; pointer to a record of type C-STRUCT. It accepts four
parameters:
;;; I, an int; S, a pointer to a string; R, a pointer to a C-
STRUCT
;;; record; and A, a pointer to the array of 10 ints.
;;;
;;; The INLINE declaration eliminates some efficiency notes about
heap
;;; allocation of alien values.
(declaim (inline c-function))
(define-alien-routine c-function
(* (struct c-struct))
(i int)
(s c-string)
(r (* (struct c-struct)))
(a (array int 10)))

;;; a function which sets up the parameters to the C function and
;;; actually calls it
(defun call-cfun ()
(with-alien ((ar (array int 10))
(c-struct (struct c-struct)))
(dotimes (i 10) ; Fill array.
(setf (deref ar i) i))
(setf (slot c-struct 'x) 20)
(setf (slot c-struct 's) "a Lisp string")

(with-alien ((res (* (struct c-struct))
(c-function 5 "another Lisp string" (addr c-
struct) ar)))
(format t "~&amp;back from C function~%")
(multiple-value-prog1
(values (slot res 'x)
(slot res 's))

;; Deallocate result. (after we are done referring to it:
;; "Pillage, *then* burn.")
(free-alien res)))))

To execute the above example, it is necessary to compile the C
routine, e.g.: `cc -c test.c && ld -shared -o test.so test.o' (In
order to enable incremental loading with some linkers, you may need to
say `cc -G 0 -c test.c')

Once the C code has been compiled, you can start up Lisp and load it
in: `sbcl'. Lisp should start up with its normal prompt.

Within Lisp, compile the Lisp file. (This step can be done separately.
You don't have to recompile every time.) `(compile-file "test.lisp")'

Within Lisp, load the foreign object file to define the necessary
symbols: `(load-shared-object "test.so")'.

Now you can load the compiled Lisp (“fasl”) file into Lisp: `(load
"test.fasl")' And once the Lisp file is loaded, you can call the Lisp
routine that sets up the parameters and calls the C function: `(test-c-
call::call-cfun)'

The C routine should print the following information to standard
output:

i = 5
s = another Lisp string
r->x = 20
r->s = a Lisp string
a[0] = 0.
a[1] = 1.
a[2] = 2.
a[3] = 3.
a[4] = 4.
a[5] = 5.
a[6] = 6.
a[7] = 7.
a[8] = 8.
a[9] = 9.

After return from the C function, the Lisp wrapper function should
print the following output:

back from C function

And upon return from the Lisp wrapper function, before the next prompt
is printed, the Lisp read-eval-print loop should print the following
return values:

10
"a C string"
 
N

nanothermite911fbibustards

Here is a link to a thread that discusses this topic but there is no
complete example.

Lars Lune has a good section on code by searching this string
"On Tue, 18 Mar 2008 01:16:00 -0700, Blackguester wrote:"
but his code is replaced with smileys and even source shows it. I
could not muster the confidence as a newbie to go into it by myself.
Unless a guru can guide and explain.

Should I pick SBCL or ECL ? I have a long term view.

8.8 Step-By-Step Example of the Foreign Function Interface

This section presents a complete example of an interface to a somewhat
complicated C function.

Suppose you have the following C function which you want to be able to
call from Lisp in the file test.c

     struct c_struct
     {
       int x;
       char *s;
     };

     struct c_struct *c_function (i, s, r, a)
         int i;
         char *s;
         struct c_struct *r;
         int a[10];
     {
       int j;
       struct c_struct *r2;

       printf("i = %d\n", i);
       printf("s = %s\n", s);
       printf("r->x = %d\n", r->x);
       printf("r->s = %s\n", r->s);
       for (j = 0; j < 10; j++) printf("a[%d] = %d.\n", j, a[j]);
       r2 = (struct c_struct *) malloc (sizeof(struct c_struct));
       r2->x = i + 5;
       r2->s = "a C string";
       return(r2);
     };

It is possible to call this C function from Lisp using the file
test.lisp containing

     (cl:defpackage "TEST-C-CALL" :)use "CL" "SB-ALIEN" "SB-C-CALL"))
     (cl:in-package "TEST-C-CALL")

     ;;; Define the record C-STRUCT in Lisp.
     (define-alien-type nil
         (struct c-struct
                 (x int)
                 (s c-string)))

     ;;; Define the Lisp function interface to the C routine.  It
returns a
     ;;; pointer to a record of type C-STRUCT.  It accepts four
parameters:
     ;;; I, an int; S, a pointer to a string; R, a pointer to a C-
STRUCT
     ;;; record; and A, a pointer to the array of 10 ints.
     ;;;
     ;;; The INLINE declaration eliminates some efficiency notes about
heap
     ;;; allocation of alien values.
     (declaim (inline c-function))
     (define-alien-routine c-function
         (* (struct c-struct))
       (i int)
       (s c-string)
       (r (* (struct c-struct)))
       (a (array int 10)))

     ;;; a function which sets up the parameters to the C function and
     ;;; actually calls it
     (defun call-cfun ()
       (with-alien ((ar (array int 10))
                    (c-struct (struct c-struct)))
         (dotimes (i 10)                     ; Fill array.
           (setf (deref ar i) i))
         (setf (slot c-struct 'x) 20)
         (setf (slot c-struct 's) "a Lisp string")

         (with-alien ((res (* (struct c-struct))
                           (c-function 5 "another Lisp string" (addr c-
struct) ar)))
           (format t "~&amp;back from C function~%")
           (multiple-value-prog1
               (values (slot res 'x)
                       (slot res 's))

             ;; Deallocate result. (after we are done referring to it:
             ;; "Pillage, *then* burn.")
             (free-alien res)))))

To execute the above example, it is necessary to compile the C
routine, e.g.: `cc -c test.c && ld -shared -o test.so test.o' (In
order to enable incremental loading with some linkers, you may need to
say `cc -G 0 -c test.c')

Once the C code has been compiled, you can start up Lisp and load it
in: `sbcl'. Lisp should start up with its normal prompt.

Within Lisp, compile the Lisp file. (This step can be done separately.
You don't have to recompile every time.) `(compile-file "test.lisp")'

Within Lisp, load the foreign object file to define the necessary
symbols: `(load-shared-object "test.so")'.

Now you can load the compiled Lisp (“fasl”) file into Lisp: `(load
"test.fasl")' And once the Lisp file is loaded, you can call the Lisp
routine that sets up the parameters and calls the C function: `(test-c-
call::call-cfun)'

The C routine should print the following information to standard
output:

     i = 5
     s = another Lisp string
     r->x = 20
     r->s = a Lisp string
     a[0] = 0.
     a[1] = 1.
     a[2] = 2.
     a[3] = 3.
     a[4] = 4.
     a[5] = 5.
     a[6] = 6.
     a[7] = 7.
     a[8] = 8.
     a[9] = 9.

After return from the C function, the Lisp wrapper function should
print the following output:

     back from C function

And upon return from the Lisp wrapper function, before the next prompt
is printed, the Lisp read-eval-print loop should print the following
return values:

     10
     "a C string"

My Sig was missed




Hey Racist and INcompetent FBI Bustards, where is the ANTHRAX Mailer ?
Where are the 4 blackboxes ? Where are the Pentagon Videos ? Why did
you release the 5 dancing Israelis compromising the whole 911
investigation ? If the Dubai Police can catch Mossad Murderers and put
the videos and Iranian Police can why cant you put the Pentagon
Videos ? If Iran police can put the AMERICAN TERRORIST, Riggi and
puting on INTERNATIONAL MEDIA a day after catching him without
TORTURE, why cant you put the INNOCENT patsies on the MEDIA. Why did
you have to LIE about Dr Afiya Siddiqui and torture that Innocent
little mother of 3 and smashing the skull of her one child ?


There are CRIMINAL cases against CIA CRIMINAL Bustards in Italian
courts.

FBI bustards paid a penalty of $5.8 million to Steven Hatfill, but
only because he was a white. They got away with MURDER of thousands of
Non-whites in all parts of the world.

Daily 911 news : http://911blogger.com

http://www.youtube.com/watch?v=tRfhUezbKLw

http://www.youtube.com/watch?v=x7kGZ3XPEm4

http://www.youtube.com/watch?v=lX18zUp6WPY
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

calling python from lisp 1

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top