Get function address (without pairing C)

Having a rather low application, I went into sitatuion, where I needed to determine the address of the Haskell function. I was able to do this with FFI, i.e. with 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 .

+4
source share
2 answers

Try the following:

 {-# 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 find Static Addresses.

+6
source

I think the documentation for FunPtr has pretty much what you want. In the short version, you use foreign import "wrapper" , as shown below:

 foreign import ccall "wrapper" getFuncAddr :: IO () -> IO (FunPtr (IO ())) 

and then if you finish this later, use freeHaskellFunPtr .

+2
source

All Articles