Trying to write minimally sufficient CL interface to GD graphic
library I've found the following difficulty. GD has a function
gdImagePng that takes Unix file pointer (type FILE * in C) as its
second argument. So the two obvious solutions could be:
- write a C function that takes name of a file opens it using
fopen and passes this file pointer to gdImagePng. Call this new
C function from CL (via FF interface)
- call fopen from CL (using foreign functions interface), get file
pointer and call gdImagePng (again using FF interface).
Both approaches don't seem much convenient. I'd rather do something like
(with-open-file (p "test.png" :direction :output :if-exists :supersede)
(gdImagePng image (stream-file-pointer p)))
if only I had stream-file-pointer function. Is something like that
possible ?
--
Vladimir Zolotykh
If you can get at the file descriptor underlying the file stream
(implementation dependent), you might be able to call fdopen to turn
the fd into a FILE*, and as long as you flush output with fflush() you
should be OK. Well, maybe not, but it's worth trying, if you don't
mind such ugliness.
-russ
Vladimir Zolotykh <······@eurocom.od.ua> writes:
> Trying to write minimally sufficient CL interface to GD graphic
> library I've found the following difficulty. GD has a function
> gdImagePng that takes Unix file pointer (type FILE * in C) as its
> second argument. So the two obvious solutions could be:
>
> - write a C function that takes name of a file opens it using
> fopen and passes this file pointer to gdImagePng. Call this new
> C function from CL (via FF interface)
>
> - call fopen from CL (using foreign functions interface), get file
> pointer and call gdImagePng (again using FF interface).
>
> Both approaches don't seem much convenient. I'd rather do something like
>
> (with-open-file (p "test.png" :direction :output :if-exists :supersede)
> (gdImagePng image (stream-file-pointer p)))
>
> if only I had stream-file-pointer function. Is something like that
> possible ?
>
> --
> Vladimir Zolotykh
Vladimir Zolotykh <······@eurocom.od.ua> writes:
> Trying to write minimally sufficient CL interface to GD graphic
> library I've found the following difficulty. GD has a function
> gdImagePng that takes Unix file pointer (type FILE * in C) as its
> second argument. So the two obvious solutions could be:
>
> - write a C function that takes name of a file opens it using
> fopen and passes this file pointer to gdImagePng. Call this new
> C function from CL (via FF interface)
>
> - call fopen from CL (using foreign functions interface), get file
> pointer and call gdImagePng (again using FF interface).
>
> Both approaches don't seem much convenient. I'd rather do something like
>
> (with-open-file (p "test.png" :direction :output :if-exists :supersede)
> (gdImagePng image (stream-file-pointer p)))
>
> if only I had stream-file-pointer function. Is something like that
> possible ?
Wouldn't using the more primitive gdImagePngPtr be easier? The doc
says it's
Identical to gdImagePng except that it returns a pointer to a
memory area with the PNG data.
I have close to zero experience with FFIs, but I'd think that this
scenario is quite common.
Andras
Simon Andr�s wrote:
> Wouldn't using the more primitive gdImagePngPtr be easier? The doc
> says it's
It had seemed the best approach before I realized that my knowledge of
ACL FF is insufficient to deal with array dynamically allocated inside
gdImagePngPtr properly. Or at least my code appeared rather clumsy. So
at last I ended up this more familiar solution:
(defmacro with-file-pointer ((var path mode) &body body)
(let ((fp (gensym "fp")))
`(let* ((,fp (fopen ,path ,mode))
(,var ,fp))
(unwind-protect
(progn ,@body)
(fclose ,fp)))))
--
Vladimir Zolotykh