Hello,
cffi-grovel is failing to compile a file. I am not certain whether the problem is the way I am using cffi-grovel (most likely), my utter lack of knowledge of C, or something else. Also I noticed recent activity by Liam Healy on linking to structures (which I did not closely follow), and I wonder if it has any bearing on this.
I want to link CL to "triangle", a library for two dimensional triangulation and meshing (http://www.cs.cmu.edu/~quake/triangle.html).
The interface to the main subroutine is defined in "triangle.h" which defines a structure "triangulateio":
struct triangulateio { REAL *pointlist; /* In / out */ REAL *pointattributelist; /* In / out */ int *pointmarkerlist; /* In / out */ int numberofpoints; /* In / out */ int numberofpointattributes; .... }
I defined a groveller lisp file libtriangle-unix.lisp with the following contents:
(define REAL "double") (include "/home/mv/external-libraries/c-code/triangle/triangle.h")
(cstruct triangulateio "triangulateio")
(Note that I did not specify any fields. I saw a post on the web suggesting that cffi would fill it in. Is that correct?)
In the asd file, I have :components ((:file "cl-triangle-package-def") (cffi-grovel:grovel-file "libtriangle-unix")))
When I load the system, a C file is generated in ~/.cache/..., and this file fails to compile, on the statement containing "sizeof(triangulateio)"
Here are the C file contents:
#define REAL double #include "/home/mv/external-libraries/c-code/triangle/triangle.h"
#include <grovel/common.h>
int main(int argc, char**argv) { FILE *output = argc > 1 ? fopen(argv[1], "w") : stdout; fprintf(output, ";;;; This file has been automatically generated by " "cffi-grovel.\n;;;; Do not edit it by hand.\n\n"); fprintf(output, "(cl:in-package #:CL-TRIANGLE)\n\n");
/* cstruct section for TRIANGULATEIO */ fprintf(output, "(cffi:defcstruct ("); fprintf(output, "triangulateio"); fprintf(output, " :size %i)", sizeof(triangulateio)); /* Line 20 */ fprintf(output, ")\n"); ...
The error message is
libtriangle-unix.c: In function ‘main’: libtriangle-unix.c:20: error: ‘triangulateio’ undeclared (first use in this function)
The same error happens if I modify the C file to explicitly declare the structure there.
Two questions: - Is my procedure incorrect (the grove lisp file, asdf specification) - I don't see why triangulateio is undefined on line 20. But that may be my lack of C knowledge.
Thanks,
Mirko
On Fri, 2012-09-21 at 16:27 -0400, Mirko Vukovic wrote: [...]
struct triangulateio { REAL *pointlist; /* In / out */ REAL *pointattributelist; /* In / out */ int *pointmarkerlist; /* In / out */ int numberofpoints; /* In / out */ int numberofpointattributes; .... }
I defined a groveller lisp file libtriangle-unix.lisp with the following contents:
(define REAL "double") (include "/home/mv/external-libraries/c-code/triangle/triangle.h")
(cstruct triangulateio "triangulateio")
that needs to be (cstruct triangulateio "struct triangulateio")
(Note that I did not specify any fields. I saw a post on the web suggesting that cffi would fill it in. Is that correct?)
No, you must declare all fields you're interested in. What the groveler does for you is figuring out the struct's total size and the fields' offsets. It's even ok if you don't declare all fields the actual struct contains Example: https://github.com/sionescu/iolib/blob/master/src/syscalls/ffi-types-unix.li... struct dirent can, and on some OSes, does have other fields but I only use the ones I listed there