passing a Handle to a C function

Kevin S. Millikin kmillikin@atcorp.com" <kmillikin@atcorp.com
Wed, 9 Jul 2003 15:24:10 -0500


Hal,

I was really hoping that someone would have a pretty answer for you by 
now.  Just this last week, I came up with a similar problem--I need to 
pass a handle to some foreign code, but in my case, the foreign code 
can treat the handle as opaque, it just needs to be able to give it 
back to Haskell when needed.

I haven't actually solved my problem in a nice way (though your posted 
code suggests a way, using the file descriptor).

> foreign import ccall "myHFile.h myCFun" c__myCFun :: Ptr CInt -> IO 
()
> myCFun :: Handle -> IO ()
> myCFun (FileHandle handleMV) = do
>   h__ <- readMVar handleMV
>   ptr <- malloc
>   poke ptr (toCInt $ haFD h__)
>   c__initVars ptr

Do you mean c__myCFun instead of c__initVars?  What is toCInt?  Is it 
doing anything wierd?

Anyway, might this work?

> foreign import ccall "myHFile.h myCFun_stub" c__myCFun :: CInt -> IO 
()

> myCFun :: Handle -> IO ()
> myCFun (FileHandle handleMV) =
>     readMVar handleMV >>= c__myCFun . toCInt . haFD

To pass a CInt (no need for Ptr here) to a stub function in C, where 
the stub function just converts the file descriptor to a FILE * and 
calls yourCFun (I mean, myCFun):

void myCFun_stub(int fd) {
    FILE *f = fdopen(fd, "w");
    myCFun(f);
    fflush(f);
}

It worked for writing to a text file in a simple test, and for writing 
to stdout.  I needed to fflush on the C side when writing to the file.

----
Kevin S. Millikin           Architecture Technology Corporation
Research Scientist          Specialists in Computer Architecture
(952)829-5864 x162          http://www.atcorp.com