I have a C program that calls a Haskell function. I want the Haskell function to be responsible for determining the size of the array (pointer) so I also want Haskell to malloc the pointer from C. I get an error when malloc_ is called in Haskell. I am not sure how to emulate the way malloc_ is called in C malloc_((void *)&ints,sizeof(int),10); into Haskell.
aux.c
void malloc_ (void **p, size_t size, int m) {
*p = malloc(size*m);
}
main.c
int *ints;
// want to call this function in Haskell, C doesn't know how large the array is
// malloc_((void *)&ints,sizeof(int),10);
int ints_size = setIntArray(ints);
for (int i = 0; i < ints_size; i++) {
printf("ints[%d]: %d\n", i, ints[i]);
}
Arrays.hs
#include "aux.h"
-- this might be wrong
foreign import ccall "malloc_" malloc_ :: Ptr (Ptr ()) -> CSize -> CInt -> IO ()
foreign export ccall "setIntArray" setIntArray :: Ptr CInt -> IO CInt
setIntArray :: Ptr CInt -> IO (CInt)
setIntArray is = do
let r = 10 :: Int
-- if I remove this and malloc in C then it is fine
malloc_ (castPtr is) (fromIntegral $ sizeOf is) (fromIntegral r)
x <- addArrayElement r 0
return $ fromIntegral x
where
addArrayElement :: Int -> Int -> IO Int
addArrayElement r pointerCounter =
case pointerCounter >= r of
True -> return r
False -> do
let x = 1234
poke (advancePtr is pointerCounter) (x :: CInt)
addArrayElement r (pointerCounter + 1)
main.cis already wrong for what you want to do, sincesetIntArray(ints)cannot modify the value ofintsitself, which it would need to do to haveintspoint to allocated memory after the call. Maybe you wanted to callsetIntArray(&ints), withsetIntArrayof typePtr (Ptr CInt) -> IO CInt?malloc_in C and not Haskell and modifies the values.intsis already a pointer. If I am not mistaken the appropriate syntax should besetIntArray(ints), just double checked, if IsetIntArrays(&ints)it gets a segmentation fault. I don't think it needs to be a double pointer, it is just 1D array being set.&intsintomalloc_, so thatmalloc_could change the value ofints... the same will be true ofsetIntArray, if you want to move the allocation there.