[cffi-devel] CFFI and GSL (spline function) help needed
![](https://secure.gravatar.com/avatar/0762d4d79abbefc81f80c09301e08f36.jpg?s=120&d=mm&r=g)
Hello, i want to use the GSL spline functionallity from within SBCL using the CFFI interface. So far i can do the "simple" functions returning pointers and/or values like the BESSEL function for example. Now i 'am trying to setup an interface for the spline function but cannot manage to handle the "gsl_interp_cpline" pointer in lisp correctly. I did copy the needed parts here for simplicity: /***************** gsl_types.h ************************/ <snip> # define GSL_VAR extern <snap> /***************** gsl_interp.h ***********************/ /* evaluation accelerator */ typedef struct { size_t cache; /* cache of index */ size_t miss_count; /* keep statistics */ size_t hit_count; } gsl_interp_accel; /* interpolation object type */ typedef struct { const char * name; unsigned int min_size; void * (*alloc) (size_t size); int (*init) (void *, const double xa[], const double ya[], size_t size); int (*eval) (const void *, const double xa[], const double ya[], size_t size, double x, gsl_interp_accel *, double * y); int (*eval_deriv) (const void *, const double xa[], const double ya[], size_t size, double x, gsl_interp_accel *, double * y_p); int (*eval_deriv2) (const void *, const double xa[], const double ya[], size_t size, double x, gsl_interp_accel *, double * y_pp); int (*eval_integ) (const void *, const double xa[], const double ya[], size_t size, gsl_interp_accel *, double a, double b, double * result); void (*free) (void *); } gsl_interp_type; /* general interpolation object */ typedef struct { const gsl_interp_type * type; double xmin; double xmax; size_t size; void * state; } gsl_interp; /* available types */ GSL_VAR const gsl_interp_type * gsl_interp_cspline; gsl_interp_accel * gsl_interp_accel_alloc(void); /********************** gsl_spline.h *********************************/ /* general interpolation object */ typedef struct { gsl_interp * interp; double * x; double * y; size_t size; } gsl_spline; gsl_spline * gsl_spline_alloc(const gsl_interp_type * T, size_t size); /********************* example.c **************************************/ <snip> gsl_interp_accel *acc = gsl_interp_accel_alloc (); gsl_spline *spline = gsl_spline_alloc (gsl_interp_cspline, 10); <snap> /*********************************************************************/ My lisp translation so far: (defpackage :cffi-user (:use :common-lisp :cffi)) (in-package :cffi-user) (pushnew #P"/usr/local/lib/" *foreign-library-directories* :test #'equal) (define-foreign-library libgslcblas (:unix (:or "libgslcblas.so.0.0.0" "libgslcblas.so.0")) (t (:default "libgslcblas"))) (use-foreign-library libgslcblas) (define-foreign-library libgsl (:unix (:or "libgsl.so.0.9.0" "libgsl.so.0")) (t (:default "libgsl"))) (use-foreign-library libgsl) ;;;; just to test the interface (defcfun "gsl_sf_bessel_J0" :double (x :double)) (format t "~A~%" (gsl-sf-bessel-J0 5d0)) ;;;; ok so far (defcfun "gsl_interp_accel_alloc" :void) (defparameter *gsl-int-acc-alloc* (gsl-interp-accel-alloc)) ;;;; looks ok so far (defctype gsl-cspline :pointer) <--- trouble (defcfun "gsl_spline_alloc" :pointer (ptr :pointer) (n :int)) (defparameter *gsl-spline-alloc* (gsl-spline-alloc gsl-cspline 10)) My problem is that i cannot set this typed struc pointer "gsl_interp_cpline" correctly. Memory allocation ? What is the "magic" trick here ? Heiko
![](https://secure.gravatar.com/avatar/9ed6ab1d1019fe41799ee83440518e36.jpg?s=120&d=mm&r=g)
Heiko Schroeter <schroete@iup.physik.uni-bremen.de> writes:
/* available types */ GSL_VAR const gsl_interp_type * gsl_interp_cspline;
(defctype gsl-cspline :pointer) <--- trouble
(defcfun "gsl_spline_alloc" :pointer (ptr :pointer) (n :int)) (defparameter *gsl-spline-alloc* (gsl-spline-alloc gsl-cspline 10))
It looks like "gsl_interp_cspline" is a global variable, not a type, so you probably want to be doing something like: (defcvar "gsl_interp_cspline" :pointer) That should define a symbol macro *GSL-INTERP-CSPLINE* that will get the value of that C variable as a foreign pointer (I must admit, it seems a little weird to me to name the symbol macro with the special variable naming convention, since it's not actually special...) James
![](https://secure.gravatar.com/avatar/0762d4d79abbefc81f80c09301e08f36.jpg?s=120&d=mm&r=g)
James Bielman <jamesjb <at> jamesjb.com> writes:
/* available types */ GSL_VAR const gsl_interp_type * gsl_interp_cspline;
It looks like "gsl_interp_cspline" is a global variable, not a type, so you probably want to be doing something like:
(defcvar "gsl_interp_cspline" :pointer)
That should define a symbol macro *GSL-INTERP-CSPLINE* that will get the value of that C variable as a foreign pointer (I must admit, it seems a little weird to me to name the symbol macro with the special variable naming convention, since it's not actually special...)
James
This seems to work ! Thanks a lot. A quick and manual hack as a test is here (a bit ugly, but just for a start...) (unless (find-package 'cffi) (asdf:oos 'asdf:load-op :cffi)) (defpackage :cffi-user (:use :common-lisp :cffi)) (in-package :cffi-user) (pushnew #P"/usr/local/lib/" *foreign-library-directories* :test #'equal) (define-foreign-library libgslcblas (:unix (:or "libgslcblas.so.0.0.0" "libgslcblas.so.0")) (t (:default "libgslcblas"))) (use-foreign-library libgslcblas) (define-foreign-library libgsl (:unix (:or "libgsl.so.0.9.0" "libgsl.so.0")) (t (:default "libgsl"))) (use-foreign-library libgsl) ;;;; ;;;(defcfun "gsl_sf_bessel_J0" :double (x :double)) ;;;(time (format t "~A~%" (gsl-sf-bessel-J0 5d0))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; declare stuff (defcfun "gsl_interp_accel_alloc" :pointer) (defcvar "gsl_interp_cspline" :pointer) (defcfun "gsl_spline_alloc" :pointer (ptr :pointer) (n :int)) (defcfun "gsl_spline_init" :int (ptr :pointer) (x :pointer) (y :pointer) (n :int)) (defcfun "gsl_spline_eval" :double (spla :pointer) (xi :double) (acca :pointer)) (defcfun "gsl_spline_free" :void (ptr :pointer)) (defcfun "gsl_interp_accel_free" :void (ptr :pointer)) ;;; Main Starts here (defparameter *gsl-int-acc-alloc* (gsl-interp-accel-alloc)) (defparameter *gsl-spline-alloc* (gsl-spline-alloc *gsl-interp-cspline* 5)) (defparameter *xarray* (foreign-alloc :double :initial-contents '(1d0 2d0 3d0 4d0 5d0))) (defparameter *yarray* (foreign-alloc :double :initial-contents '(1d1 2d1 3d1 4d1 5d1))) (gsl-spline-init *gsl-spline-alloc* *xarray* *yarray* 5) (format t "~A~%" (gsl-spline-eval *gsl-spline-alloc* 3.4d0 *gsl-int-acc-alloc*)) (foreign-free *xarray*) (foreign-free *yarray*) (gsl-spline-free *gsl-spline-alloc*) (gsl-interp-accel-free *gsl-int-acc-alloc*) Heiko
participants (2)
-
Heiko Schroeter
-
James Bielman