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)