Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/skeeto/elisp-ffi
Emacs Lisp Foreign Function Interface
https://github.com/skeeto/elisp-ffi
Last synced: 2 months ago
JSON representation
Emacs Lisp Foreign Function Interface
- Host: GitHub
- URL: https://github.com/skeeto/elisp-ffi
- Owner: skeeto
- License: unlicense
- Created: 2014-04-03T02:32:55.000Z (almost 11 years ago)
- Default Branch: master
- Last Pushed: 2017-05-18T22:31:00.000Z (over 7 years ago)
- Last Synced: 2024-10-31T21:43:04.399Z (3 months ago)
- Language: C++
- Size: 41 KB
- Stars: 86
- Watchers: 11
- Forks: 8
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Emacs Lisp Foreign Function Interface
This library provides an FFI for Emacs Lisp so that Emacs programs can
invoke functions in native libraries. It works by driving a subprocess
to do the heavy lifting, passing result values on to Emacs.* Read [how it works](http://nullprogram.com/blog/2014/04/26/).
## Examples
A function signature is described by a vector of type keywords. The
first element is the return value and the rest are the types of the
arguments. Integers, floats, strings, and pointer values obtained from
previous calls are allowed as arguments.~~~el
;; srand(0) and rand()
(ffi-call nil "srand" [:void :uint32] 0)
;; => :void
(ffi-call nil "rand" [:sint32])
;; => 1102520059;; cos(1.2)
(ffi-call "libm.so" "cos" [:double :double] 1.2)
;; => 0.362357754476674;; time(NULL);
(ffi-call nil "time" [:uint64 :pointer] nil)
;; => 1396496875;; getenv("DISPLAY")
(ffi-get-string (ffi-call nil "getenv" [:pointer :pointer] "DISPLAY"))
;; => ":0"
~~~The function signatures (CIFs) and handles are cached so that they
don't need to be redefined/fetched/loaded by the subprocess on each
function invocation.Getting the function signature wrong may crash the subprocess (the FFI
"context"), but Emacs itself will be safe from crashes.## Support
You'll need a C++11 compiler and [libffi][libffi] in order to build
the native helper program. Run `make` before attempting to use the FFI
from within Emacs.Like the underlying libffi, there is no explicit support for calling
variadic functions, but it may still sometimes work.There's no support for parsing/handling structs, so these must be read
raw. This will probably not change.There's not *yet* any support for building closures, so that native
functions can call back to Emacs.Emacs will not be able to handle very large integer values, because
Emacs' primitive integers are always slightly smaller than the
system's word size (tagged ints). This is especially an issue with
32-bit Emacs. Pointers are stored as symbols, evading these integer
limitation.## Internals
The helper subprocess is a stack machine that operates by a very
simple, human-readable bytecode. The bytecode itself is primarily
documented in the C++ source. Emacs pushes values onto the stack and
invokes native function calls on them, leaving the result on the
stack.[libffi]: http://sourceware.org/libffi/