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.
Again, thanks for any and all assistance. Cheers /Greg Bennett
your Hell-function has return value void so there is no return (apart from that "return 0" that should not be there), hence the NIL. Printf prints to stdout so maybe you just didn't see it?
On 27.11.2013 17:41, Greg Bennett wrote:
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.
Again, thanks for any and all assistance. Cheers /Greg Bennett
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);