Having a rather low level application, I came into a sitatuion where I needed to determine the address of a Haskell function. I was able to do that with FFI, that is C, but I would like to do it directly in Haskell.
Here is my current solution with FFI:
main.hs:
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
import Foreign
import Foreign.C.Types
import Text.Printf
foreign import ccall "getFuncAddr"
getFuncAddr :: CULong
main :: IO ()
main = do
printf "0x%016x\n" (fromIntegral getFuncAddr :: Word64)
foreign export ccall func :: IO ()
func :: IO ()
func = do
printf "hello world\n"
ffi.c:
void func(void);
unsigned long getFuncAddr(void)
{
return (unsigned long) func;
}
Makefile:
all: main
./$<
objdump -D $< | grep '<func>'
main: main.hs ffi.c
ghc --make -O2 $^ -o $@
as always, also available as a gist.
Try this:
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
import Foreign
import Foreign.C.Types
import Text.Printf
foreign import ccall "&func"
funcaddr :: FunPtr (IO ())
main :: IO ()
main = do
printf "0x%016x\n" (fromIntegral (ptrToIntPtr (castFunPtrToPtr funcaddr)) :: Int)
foreign export ccall func :: IO ()
func :: IO ()
func = do
printf "hello world\n"
See this section of the Haskell 2010 report, and look for "Static Addresses."
I think the documentation for FunPtr has pretty much what you want. The short version is you use foreign import "wrapper"
, as follows:
foreign import ccall "wrapper"
getFuncAddr :: IO () -> IO (FunPtr (IO ()))
and then if you're done with it later, use freeHaskellFunPtr
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With