[gambit-list] is this a bug in ffi?

Álvaro Castro-Castilla alvaro.castro.castilla at gmail.com
Mon Feb 6 09:59:48 EST 2012


Thank you Marc. Those are all better solutions than my wrapper function.

Best regards

Álvaro



2012/2/6 Marc Feeley <feeley at iro.umontreal.ca>

>
> On 2012-02-06, at 8:08 AM, Marc Feeley wrote:
>
> > I can reproduce the problem.  It seems to be a bug.  I'll look into it
> today.
>
> I can confirm that it is a bug in the C-interface which occurs with opaque
> types (such as (c-define-type foo "foo")), and "struct" and "union" types
> when the body of the c-lambda is inline code (the case where the c-lambda
> body is a function name is handled correctly).
>
> I'll work on a fix.
>
> In the meantime, you can use one of the styles given in the attached
> example.
>
> Marc
>
>
> (c-declare #<<end-of-c-declare
>
> #include <stdio.h>
>
> typedef enum { A, B, C } foo;
>
> void f(foo x) { printf("%d\n", x); }
>
> end-of-c-declare
> )
>
>
> ;;;---------------------------------------------------------------------------
>
> ;#|
>
> ;; This interface to the "foo" enum type works on C and C++ compilers.
> ;; The use of ___ASSIGN_NEW_WITH_INIT is needed to avoid a bug in the
> ;; C-interface that occurs when the body of the c-lambda is not the
> ;; name of a function (i.e. when the body is inline code).
>
> (c-define-type foo "foo")
>
> (define A
>  ((c-lambda () foo "___ASSIGN_NEW_WITH_INIT(___result_voidstar,foo,A);")))
>
> (define B
>  ((c-lambda () foo "___ASSIGN_NEW_WITH_INIT(___result_voidstar,foo,B);")))
>
> (define C
>  ((c-lambda () foo "___ASSIGN_NEW_WITH_INIT(___result_voidstar,foo,C);")))
>
> (define f (c-lambda (foo) void "f"))
> ;|#
>
>
> ;;;---------------------------------------------------------------------------
>
> #|
>
> ;; This interface to the "foo" enum type causes a bug in the
> ;; C-interface on C and C++ compilers.
>
> (c-define-type foo "foo")
>
> (define A ((c-lambda () foo "___result = A;")))
> (define B ((c-lambda () foo "___result = B;")))
> (define C ((c-lambda () foo "___result = C;")))
>
> (define f (c-lambda (foo) void "f"))
> |#
>
>
> ;;;---------------------------------------------------------------------------
>
> #|
>
> ;; This interface works on C and C++ compilers, but is klunky.
>
> (c-declare #<<end-of-c-declare
>
> foo get_A() { return A; }
> foo get_B() { return B; }
> foo get_C() { return C; }
>
> end-of-c-declare
> )
>
> (c-define-type foo "foo")
>
> (define A ((c-lambda () foo "get_A")))
> (define B ((c-lambda () foo "get_B")))
> (define C ((c-lambda () foo "get_C")))
>
> (define f (c-lambda (foo) void "f"))
> |#
>
>
> ;;;---------------------------------------------------------------------------
>
> #|
>
> ;; This is an alternate interface to the "foo" enum type.  The
> ;; explicit cast in the definition of "f" is required when compiling
> ;; with a C++ compiler because the conversion from int to enum is not
> ;; implicit in C++.
>
> (c-define-type foo int) ;; NOTE: using "int" type for "foo"
>
> (define A ((c-lambda () foo "___result = A;")))
> (define B ((c-lambda () foo "___result = B;")))
> (define C ((c-lambda () foo "___result = C;")))
>
> (define f (c-lambda (foo) void "f((foo)___arg1);")) ;; NOTE: explicit cast
> |#
>
>
> ;;;---------------------------------------------------------------------------
>
> (f A)
> (f B)
> (f C)
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20120206/28131b43/attachment.htm>


More information about the Gambit-list mailing list