有一个相当低级别的应用程序,我进入了一个sitatuion我需要确定Haskell函数的地址。我能用FFI做到这一点,就是C,但我想直接在Haskell中做。
这是我目前使用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;
}
生成文件:
all: main
./$<
objdump -D $< | grep '<func>'
main: main.hs ffi.c
ghc --make -O2 $^ -o $@
一如既往,也可作为gist。
答案 0 :(得分:6)
试试这个:
{-# 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"
请参阅this section of the Haskell 2010 report,然后查找“静态地址”。
答案 1 :(得分:2)
我认为FunPtr的文档非常符合您的要求。简短版本是您使用foreign import "wrapper"
,如下所示:
foreign import ccall "wrapper"
getFuncAddr :: IO () -> IO (FunPtr (IO ()))
然后如果您以后完成,请使用freeHaskellFunPtr
。