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"))