I developed a very simple FFI for the Wiring PI library, to be able to control a Raspberry Pi using Racket.
This worked well, but only covers the base functionality. I wanted to extend this to also use the lcd.h from the libwiringPiDev.so, so that I could create an FFI to control an LCD.
Normally, when you compile a C file that uses the LCD, you tag both the standard library and the development library when compiling:
-lwiringPi -lwiringPiDev
In my LCD FFI I did the following:
(define-ffi-definer define-lcd
(ffi-lib "usr/lib/libwiringPiDev.so"))
However, when I try to require that racket file, I run into:
; ffi-lib: couldn't open "/usr/lib/libwiringPiDev.so"
; (/usr/lib/libwiringPiDev.so: undefined symbol: digitalRead) [,bt for
; context]
The digitalRead function exists in the base library but not in the dev library...how do I do a "FFI with dependencies" so that Racket can properly manage both libraries to be able to find the necessary symbols?
Try loading libwiringPi.so first in global mode, then load libwiringPiDev.so:
(define-ffi-definer define-lcd
(ffi-lib "/usr/lib/libwiringPi.so" #:global? #t))
(define-ffi-definer define-lcd-dev
(ffi-lib "/usr/lib/libwiringPiDev.so"))
The #:global? #t
argument corresponds to setting the RTLD_GLOBAL
flag in the call to dlopen
, and the man page for dlopen (on my Linux system) says
RTLD_GLOBAL
The symbols defined by this shared object will be made available for symbol resolution of subsequently loaded shared objects.