"KAKIHARA" == KAKIHARA Norihiro
writes:
I want to use ForeignObj for large transient data, but Hugs ForeignObj implementation is quite mysterious...
I wonder if you're being confused by the corresponding feature in GHC (also called ForeignObj) which goes a long way beyond what Hugs provides (and is a good deal harder to implement)?
primitive makeForeignObj :: Addr{-x-} -> Addr{-free-} -> IO The latter argument of makeForeignObj is a mystery.
1. I thought it is a pointer of function (with type of [void (*)(void *);] ?).
That's what it is.
foreign import "foo" "newFO" newFO :: IO Addr foreign import "foo" "delFO" delFO :: Addr -> IO ()
newFO >>= (\fo -> makeForeignObj fo (unsafeCoerce delFO))
This code causes an unexpected signal (probably the implementation of Addr -> IO () is different from C form).
You bet it will. It's meant to be a pointer to a C function but foreign import generates Haskell functions. Their calling conventions are incredibly different in Hugs: different address space, different argument passing mechanism, different representation of every data type. The clue here is that you have to use unsafeCoerce. If we meant you to pass something with Haskell type: Addr -> IO () then that would be the type. (It is almost impossible to write a correct Haskell program that uses unsafeCoerce. Anyone using it is almost certainly doing something very wrong.)
2. `foreign label' is valid?
foreign import "foo" "newFO" newFO :: IO Addr foreign label "foo" "delFO" delFO :: Addr
newFO >>= (\fo -> makeForeignObj fo delFO)
No, it isn't.
That ought to work but foreign label hasn't been tested very thoroughly. I'll try to get round to it sometime soon (but no promises).
3. Then I try to get the pointer of delFO directly (Fortunately lcc-win32 3.1 allows internal global variables viewable, however, I suppose other C compilers do not...).
foreign import "foo" "newFO" newFO :: IO Addr foreign import "foo" "delFO" delFO :: Addr -> IO () foreign import "foo" "getDelFO" getDelFO :: IO Addr
getDelFO >>= (\del -> newFO >>= (\fo -> makeForeignObj fo del))
It works as expected.
Sounds like foreign label may be broken. -- Alastair Reid reid@cs.utah.edu http://www.cs.utah.edu/~reid/