[cffi-devel] C to Lisp

Stas Boukarev stassats at gmail.com
Wed Nov 27 17:15:54 UTC 2013


Greg Bennett <gwbennett at sentex.ca> writes:

> Good morning,
> I (think I) might be close to getting a result in having a C function
> return its output to Lisp. I shall be very grateful for comments and
> corrections to what I have done, and thank readers for their patience.
>
> Here is the C-function from which I wish to get the result  Hello Lisp
> from C  on the lisp side:
> /* Hello.c  program */
>
>
> #include<stdio.h>
>
> void Hello(void)
> {
>     printf("Hello Lisp from C\n");
>     return 0 ;
>
> }
>
> At the end of the process, I hope to be able to do this on the Lisp
> side:
> (defcfun ("Hello" HiFromC) (:void))
> and then
> (HiFromC) -> Hello Lisp from C
>
> Both C and Lisp sessions are below in case details are relevant.
> Somewhere I have missed a critical element.
>
> Thanks to a message from Luis Oliveira pointing me to the necessity of
> using a shared library as the intermediary between C and Lisp. There
> seem to be as many recipes for creating such libraries as there are
> posters of the topic, and as many variations on the code too. I have
> put together the C side following very much this page:
>  www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html
>
> In file /home/gwbennett/Hello.h
> #ifndef Hello_h__
> #define  Hello_h__
>
> extern void Hello(void);
>
> #endif  // Hello_h__
>
> In file /home/gwbennett/Hello.c
> /* Hello  program */
>
>
> #include<stdio.h>
>
> void Hello(void)
> {
>     printf("Hello Lisp from C\n");
>     return 0 ;
>
> }
>
> In file main.c
> /* This is main.c to go with Hello.c,h */
> #include <stdio.h>
> #include "Hello.h"
>
> int main (void)
> {
> 	Hello();
> 	return 0;
> }
>
> Then
> gcc -c -Wall -Werror -fpic Hello.c -> OK
> gcc -shared -o libfHello.so Hello.o -> OK
> gcc -L/home/gwbennett -Wall -o test main.c -lHello -> OK
>
> Step 4 of the above page is about making the library visible.
> I have tried all 3 routes with the same results; at the moment I have
> taken the path of installing libHello.so in /usr/lib (and
> in /usr/loca/lib too)as described in the Section  Using ldconfig to
> modify ld.so
>
> gcc -Wall -o test main.c -lfoo -> OK
> ldd test | grep foo -> /usr/locl/lib/libHello.so (0x00007f946c0c4000)
> ./test -> Hello Lisp from C
>
> so things seem to work down the C-side
>
> On the Lisp side I (hope I) am following the cffi manual page 10. I
> assume that cffi looks for shared libraries in the same sort of 'system'
> places as C, but just in case, see page 106 on
> *foreign-library-directories*.
>
> Start ccl version 1.9-r15972M (LinuxX8664)
> (require :cffi) -> OK
> (defpackage :cffi-user
>   (:use :common-lisp :cffi)) -> OK
> (in-package :cffi-user) -> OK
> ;P106
> (pushnew #P/"usr/lib" *foreign-library-directories* :test #'equal) -> OK
> (pushnew #P"/usr/local/lib" *foreign-library-directories* :test #'equal)
> -> OK
> (load-foreign-library '(:default "LibHello")) -> OK
> ;; I think I should be able to define the C -> Lisp name function
> (defcfun ("Hello" HiFromC) (:void)) -> HIFROMC
> ;; and execute it to get the message
> (HiFromC) -> NIL
>
> ;; .. so evidently I have not completely understood what is necessary to
> achieve the desired result.
Are you aware of the difference between printing to the standard output
and returning a result?

And all you have to do is:
#include <stdio.h>

void hello () {
     printf("Hello Lisp from C\n");
}

gcc foo.c -fPIC -o foo.so

? (cffi:load-foreign-library "/tmp/foo.so")
#<FOREIGN-LIBRARY FOO.SO-6780 "foo.so">
? (cffi:foreign-funcall "hello")
Hello Lisp from C
NIL
?

If you still don't see any output,
just add fflush(stdout);

-- 
With best regards, Stas.



More information about the cffi-devel mailing list