To create the dynamic module we need a small c file that wraps the GSL function and adds it to the Emacs environment. Here is the smallest example I could come up with for this one function. Basically, we create a function that takes the emacs environment and arguments, extract what we want from them, and use that to calculate what we need and return it to the environment. Then we register that function and define what the module provides in emacs_module_init.

#include <assert.h> #include <gsl/gsl_sf_bessel.h> #include "emacs-module.h" int plugin_is_GPL_compatible ; static emacs_value F_gsl_sf_bessel_J0 ( emacs_env * env , ptrdiff_t nargs , emacs_value args [], void * data ) { assert (nargs == 1); double x = env->extract_float (env, args[0]); return env->make_float (env, gsl_sf_bessel_J0 (x)); } int emacs_module_init ( struct emacs_runtime * ert ) { emacs_env * env = ert->get_environment(ert); emacs_value gsl_sf_bessel_J0_fn = env->make_function(env, 1, 1, F_gsl_sf_bessel_J0, "Regular cylindrical Bessel function of zeroth order, J_0(x)" , NULL ); emacs_value Qfset = env->intern(env, "fset" ); emacs_value Q_gsl_sf_bessel_J0 = env->intern(env, "gsl-sf-bessel-J0" ); emacs_value fset_args [] = { Q_gsl_sf_bessel_J0, gsl_sf_bessel_J0_fn }; env->funcall(env, Qfset, 2, fset_args); emacs_value Qprovide = env->intern(env, "provide" ); emacs_value Q_gsl_sf_bessel = env->intern(env, "gsl-sf-bessel" ); emacs_value provide_args [] = { Q_gsl_sf_bessel }; env->funcall(env, Qprovide, 1, provide_args); return 0; }

Now we compile it into a shared library.

gcc -Wall -I/usr/local/include -fPIC -c gsl-sf-bessel.c gcc -shared -L/usr/local/include -lgsl -o gsl-sf-bessel.so gsl-sf-bessel.o

That creates our shared library in gsl-sf-bessel.so.

ls *.so

(add-to-list 'load-path "/Users/jkitchin/vc/blogofile-jkitchin.github.com/_blog/dynamic-module/" ) ( require ' gsl-sf-bessel ) (gsl-sf-bessel-J0 5.0)

-0.17759677131433826

That is the same answer as we got before. Here is the documentation we defined. It could use some improvement, e.g. to note that the argument has to be a float, and that only one argument is allowed. I am not sure why the signature doesn't show a single argument.

(describe-function 'gsl-sf-bessel-J0)

gsl-sf-bessel-J0 is a Lisp function. (gsl-sf-bessel-J0 &rest ARGS) For more information check the manuals. Regular cylindrical Bessel function of zeroth order, J_0(x)

I am not a very skilled C-programmer yet, so I don't know how hard it would be to make this function accept integers as well, or to vectorize it so you could have an arbitrary number of args to it and return a list.