Greg Bennett gwbennett@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);