To: Helmut Eller; Kick Damien-DKICK1
Cc: [EMAIL PROTECTED]
Subject: RE: CMU CL FFI and variadic C functions
Helmut Eller [[EMAIL PROTECTED]] wrote:
> Kick Damien-DKICK1 <[EMAIL PROTECTED]> writes:
> > Well, it would be possible but not nearly as "clean" as being able
> > to use some hyptothetical FFI equivalent of '&rest'/'...'.
> How should the hypothetical FFI equivalent for, say printf, look
> like? And why would that be more convenient than this:
> (defun test ()
> (alien:alien-funcall
> (alien:extern-alien "printf"
> (function c-call:void
> c-call:c-string
> c-call:int
> c-call:double
> c-call:char))
> "int: %d %f %c" 1 2.3d0 (char-int #\newline)))
Well, I didn't think that this would work because the prototype for
'printf' is not actually 'void printf(const char*, int, double, char)'
but rather 'void printf(const char*, ...)' and I thought that one had
to use the correct prototype for a function type.
> ?
I would say that my hypothetical FFI equivalent for 'printf' would
look pretty much like the example you provided <smile>. Only, it
didn't seem to work like I had hoped it would. Did I forget to do
something, e.g. did I forget an appropriate '(load-foreign #|
... |#)'?
* (defun test ()
(alien:alien-funcall
(alien:extern-alien "printf"
(function c-call:void
c-call:c-string
c-call:int
c-call:double
c-call:char))
"int: %d %f %c" 1 2.3d0 (char-int #\newline)))
TEST
* (test)
Compiling LAMBDA (#:G846 #:G847 #:G848 #:G849 #:G850):
Compiling Top-Level Form:
int: 1 2.300000
* (defun test-1 ()
(alien:alien-funcall (alien:extern-alien "printf"
(function c-call:void c-call:c-string c-call:int c-call:int))
"this is my example: %d %d" 6 9))
TEST-1
* (test-1)
Compiling LAMBDA (#:G851 #:G852 #:G853 #:G854):
Compiling Top-Level Form:
* (defun test-1 ()
(alien:alien-funcall (alien:extern-alien "printf"
(function c-call:void
c-call:c-string
c-call:int
c-call:int))
"this is my example: %d %d\n"
6
9))
TEST-1
* (test-1)
Compiling LAMBDA (#:G855 #:G856 #:G857 #:G858):
Compiling Top-Level Form:
* (test)
this is my example: 6 9this is my example: 6 9nint: 1 2.300000
* (test-1)
*
I would have expected '(test-1)' to produce some output. Or is that
because of buffering?
* (defun test-2 ()
(alien:alien-funcall
(alien:extern-alien "printf"
(function c-call:void
c-call:c-string
c-call:int
c-call:int))
"this is my example: %d %d\\n"
6
9)
(alien:alien-funcall
(alien:extern-alien "fflush"
(function c-call:int
(* t)))
(alien:extern-alien "stdout"
(* t))))
TEST-2
* (test-2)
Compiling LAMBDA (#:G865 #:G866 #:G867 #:G868):
Compiling Top-Level Form:
Error in function COMMON-LISP::FOREIGN-SYMBOL-ADDRESS-AUX:
Unknown foreign symbol: "stdout"
Restarts:
0: [ABORT] Return to Top-Level.
Debug (type H for help)
(COMMON-LISP::FOREIGN-SYMBOL-ADDRESS-AUX "stdout")
0] 0
*
<grumble> How to get ahold of 'stdout'? How to define a 'FILE*', as
this is supposed to be an opaque type? Anyway, I'll keep looking at
how to get 'fflush' into an 'extern-alien'. Thanks a million for the
pointer. I'll keep experimenting with this and see where it gets me.
--
Damien Kick