From: Sam S. <sd...@gn...> - 2003-06-17 13:47:35
|
> * In message <291...@ww...> > * On the subject of "FFI Code Generation Bug" > * Sent on Tue, 17 Jun 2003 02:13:08 +0200 (MEST) > * Honorable Scott Williams <or...@gm...> writes: > > If more than one foreign function has a user-defined struct for a > return type, the C compiler gets confused. When the following file is > compiled as a module: > > ----[ testffi.lisp ]------ > (defpackage "TESTFFI" > (:use "FFI" "COMMON-LISP")) > (in-package "TESTFFI") > > (default-foreign-language :stdc) > > (def-c-struct type1 > (arg1 int)) > > (def-call-out func1 > (:return-type type1)) > > (def-call-out func2 > (:return-type type1)) > ---[ end testffi.lisp ]---- > > I get the following function definitions in the testffi.c file: > > extern struct TYPE1 { int ARG1; } (func1)(); > extern struct TYPE1 { int ARG1; } (func2)(); > > which results in the following compiler error: > > testffi.c:14: redefinition of `struct TYPE1' > make[1]: *** [testffi.o] Error 1 > > This problem does not occur if TYPE1 is only used in argument declarations. > A possible solution is to output a > struct TYPE1 { int ARG1; }; > when the def-c-struct command is encountered, and then refer to that type as > "struct TYPE1" instead of redeclaring the structure each time it is > used. indeed. I am not sure why we are not doing that, but I _am_ sure there was a compelling reason for that. e.g., the appended patch will solve your problem, but might introduce others. I hope Joerg will chime in with his insight. > Another possible solution is to avoid naming the struct, which would result in > the following code: > extern struct { int ARG1; } (func1)(); > extern struct { int ARG1; } (func2)(); > which does not cause a compiler error. we did that before, it caused other problems. > I don't know anything about the internal mechanisms clisp uses to > generate code for the FFI, otherwise i'd fix it myself :o) see TO-C-TYPEDECL in clisp/src/foreign1.lisp. -- Sam Steingold (http://www.podval.org/~sds) running RedHat9 GNU/Linux <http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/> <http://www.mideasttruth.com/> <http://www.palestine-central.com/links.html> A poet who reads his verse in public may have other nasty habits. Index: foreign1.lisp =================================================================== RCS file: /cvsroot/clisp/clisp/src/foreign1.lisp,v retrieving revision 1.40 diff -u -w -b -u -b -w -i -B -r1.40 foreign1.lisp --- foreign1.lisp 12 May 2003 10:43:18 -0000 1.40 +++ foreign1.lisp 17 Jun 2003 13:34:59 -0000 @@ -560,11 +560,8 @@ (macrolet ((with-to-c ((class typename &key (tname '(gensym "t"))) &body body) `(let ((,typename (format nil "~A ~A" ,class ,tname))) - (unwind-protect - (progn (setf (gethash c-type *type-table*) - ,typename) - ,@body) - (setf (gethash c-type *type-table*) nil))))) + (setf (gethash c-type *type-table*) ,typename) + ,@body))) (case (ctype-type c-type) (c-struct (cond ((sys::memq :typedef (svref c-type 2)) |