I'm having a problem defining/using a foreign struct for my package GSLL (http://common-lisp.net/project/gsll), an interface to the GNU Scientific Library (http://www.gnu.org/software/gsl/), written in C. I am trying to handle complex numbers; GSL has a struct defined to represent complex numbers in /usr/include/gsl/gsl_complex.h: typedef struct { double dat[2]; } gsl_complex; So I define (cffi:defcstruct complex-double-c (dat :double :count 2)) I set this value with a function (defun complex-to-gsl-df (number) (let* ((gsl (cffi:foreign-alloc 'complex-double-c)) (datslot (cffi:foreign-slot-pointer gsl 'complex-double-c 'dat))) (setf (cffi:mem-aref datslot :double 0) (realpart number) (cffi:mem-aref datslot :double 1) (imagpart number)) gsl)) When I pass a complex number generated with this function to a GSL function, I always get the following result: the real part is what I specified for the imaginary part, and the imaginary part is the number 5.2635442471208903e-315, which I discovered is the single-float number -1.0f0 interpreted as a double float (I don't know if that's significant). So for example the function #'test-set-all should set every element of the complex vector to the same number 3+4i, but I get 4+5.2635442471208903e-315i: (letm ((intvec (vector-complex-double-float 2))) (test-set-all intvec #c(3.0d0 4.0d0)) (maref intvec 1)) #C(4.0 5.2635442471208903e-315)
There is a GSL function that sets the real and imaginary parts of the struct (in C of course). When I use this, I get the answer I expect. Unfortunately, it's more restricted than setting the structure in CL, so I'd like to solve the structure problem.
My platform is SBCL 0.9.16, amd64 Debian (stable). I have a feeling I have misinterpreted the defcstruct usage. Any ideas?
Thanks, Liam
On Wed, Jun 11, 2008 at 2:44 AM, Liam Healy lnp@healy.washington.dc.us wrote:
There is a GSL function that sets the real and imaginary parts of the struct (in C of course). When I use this, I get the answer I expect. Unfortunately, it's more restricted than setting the structure in CL, so I'd like to solve the structure problem.
I'm surprised that works. It seems that GSL's complex operators are passed gsl_complex structs by value. That is not supported by CFFI. Unless GSL provides another way to handle complex values, you'll probably need to write C wrappers for each complex operator that take two doubles and pass them as a struct. (Or a single wrapper that calls a function pointer, I suppose.)
OTOH, CL already has all of these operators so perhaps you're doing something else. Can you show me an example?