4

かなり低レベルのアプリケーションを持っていたので、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;
}

Makefile:

all: main
    ./$<
    objdump -D $< | grep '<func>'

main: main.hs ffi.c
    ghc --make -O2 $^ -o $@

いつものように、要点としても利用できます。

4

2 に答える 2

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"

Haskell 2010レポートのこのセクションを参照し、「静的アドレス」を探してください。

于 2012-06-11T14:52:21.440 に答える
2

FunPtrのドキュメントには、ほとんどあなたが望むものがあると思います。短いバージョンはforeign import "wrapper"、次のように使用します。

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

後でそれを終えた場合は、を使用しますfreeHaskellFunPtr

于 2012-06-10T10:47:07.753 に答える