ForeignObj Finalizer in Hugs
KAKIHARA Norihiro
YIU04646@nifty.com
Wed, 27 Jun 2001 23:40:22 +0900
I want to use ForeignObj for large transient data,
but Hugs ForeignObj implementation is quite mysterious...
Three ForeignObj interfaces are described as such in exts/Foreign.hs.
primitive makeForeignObj :: Addr{-x-} -> Addr{-free-} -> IO ForeignObj
primitive writeForeignObj :: ForeignObj -> Addr -> IO ()
primitive eqForeignObj :: ForeignObj -> ForeignObj -> Bool
The latter argument of makeForeignObj is a mystery.
1.
I thought it is a pointer of function
(with type of [void (*)(void *);] ?).
foreign import "foo" "newFO" newFO :: IO Addr
foreign import "foo" "delFO" delFO :: Addr -> IO ()
primitive unsafeCoerce "primUnsafeCoerce" :: a -> b
newFO >>= (\fo ->
makeForeignObj fo (unsafeCoerce delFO))
This code causes an unexpected signal (probably the implementation of
Addr -> IO () is different from C form).
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.
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.
But I think such description is not appropriate!
Variables in DLL are not always viewable by another program.
How I should use ForeignObj finalizer in Hugs?
-- KAKIHARA Norihiro
[The following code was workable in my environment...]
********** main.c **********
#include <windows.h>
#include <stdio.h>
BOOL WINAPI LibMain(HINSTANCE hInstance,
DWORD fdwReason,
LPVOID lpReserved) {
return TRUE;
}
extern int *newObj(void) {
int *i;
i = (int*)malloc(sizeof(int));
*i = 5;
printf("CREATED %d\n", *i);
return i;
}
static void delObj(int *i) {
printf("DELETED %d\n", *i);
free(i);
}
extern void *getDelObj(void) {
return (void*)delObj;
}
******** foreignObj.hs **********
import Foreign
foreign import "foreignObj" "newObj" newObj :: IO Addr
foreign import "foreignObj" "getDelObj" getDelObj :: IO Addr
test :: IO ()
test =
getDelObj >>=(\del ->
newObj >>= (\obj ->
makeForeignObj obj del) >>= (\_ ->
putStr "End Program"))