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

Marc Feeley feeley at iro.umontreal.ca
Mon Feb 6 09:46:45 EST 2012


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)




More information about the Gambit-list mailing list