FFI позволяет звать функции на другом языке (например С). А binding - это уже готовая обертка обычно (может поверх FFI или как то иначе). Она выглядит как либа на твоем языке, но реализованна поверх другого языка.
Допустим, есть программа на Лиспе, и есть функция на Си.
Какие условия должны быть выполнены, чтобы я смог из Лиспа вызвать сишную функцию?
Как выглядит процесс создания биндинга? Чисто логически, надо как-то дать знать основному языку, что есть функции с некоторыми именами. Как это сделать?
Касательно Лиспа есть вот, например, библиотека CFFI.
там есть базовые примитивы, foreign-funcall-pointer, foreign-funcall(фактически - обертка над foreign-funcall-pointer) и defcfun(которая суть обертка над foreign-funcall)
вызывать, скажем, atoi можно так:
(cffi:foreign-funcall "atoi" :string "1234567890" :int)
(вернет число 1234567890, соответственно)
можно так:
(сначала получаем указатель на функцию atoi)
(defvar atoi-fptr (cffi:foreign-symbol-pointer "atoi"))
(и скармливаем его foreign-funcall-pointer первым аргументом)
(cffi:foreign-funcall-pointer atoi-fptr () :string "1234567890" :int)
а можно сначала завернуть это в defcfun
(cffi:defcfun atoi
:int
(arg :string))
и вызывать совсем как функцию лиспа:
(atoi "1234567890")
биндинги это по сути набор вот таких оберток.
вот тут есть довольно неплохой мануал по cffi:
http://common-lisp.net/project/cffi/manual/html_node/index.html
естественно, если функция находится в сторонней шаред-библиотеке, эту библиотеку нужно сначала подгрузить в лисповский рантайм функцией cffi:load-foreign-library
Ааа, кажется проясняется: с помощью load-foreign-library получаем имена функций библиотеки (т.е. указатель на адрес в памяти, где они содержатся) и после приведения типов начинаем их использовать.
А байндинги нужны для того же самого, но никаких преобразований над данными/кодом делать не нужно.
Правильно?
Но биндинги они тоже разные бывают.
Чтобы манипуляция "чужими" функциями и данными не отличалась от "родных" это надо немало постараться, на самом деле :)