I want to foreign import a function from some c header, but how to deal with the stderr of type FILE* which defined as:
extern FILE* __stderrp;
#define stderr __stderrp
Maybe not precisely. I use c2hs for my ffi work, and already have:
{#pointer *FILE as File foreign finalizer fclose newtype#}
but I can not import stderr like this:
foreign import ccall "stdio.h stderr" stderr :: File
My c function has the signature:
void func(FILE*);
I can import func with c2hs:
{#fun func as ^ {`File'} -> `()'#}
I need to use stderr to run func:
func(stderr);
I am noob with the foreign import mechanism. It seems I can not import stderr in this way.
ps. Maybe I would wrap my func in a new function
void func2(void){func(stderr);}
This is a workaround, but seems not clean.
It's not unusual to require some kind of "shim" when writing FFI code for Haskell, and I'd encourage you to just write a helper function:
and use that (see example at the bottom of this answer).
However, I was able to get the following minimal example to work by using the vanilla FFI's support for static pointers -- it doesn't import
stderr
directly, but imports a pointer to thestderr
pointer. This kind of import is not directly supported by c2hs, so the interface code is ugly, and I don't think there's any way to avoid having to fetch thestderr
pointer value in the IO monad, independent of whether or not you use c2hs.For comparison, this minimal example with the helper function looks much cleaner at the Haskell level:
Note that in both these examples, I removed your
fclose
finalizer. You probably don't want Haskell arbitrarily deciding it's a good time to closestderr
on you.