我有一个关于在Haskell FFI和GHC的交互模式的问题再次.
考虑FFISo.hs
:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import qualified Data.ByteString.Char8 as B
import FFIFun.Foo
main :: IO ()
main = do
B.putStrLn "main"
callMeFromC
callMeFromHaskell
return ()
Run Code Online (Sandbox Code Playgroud)
c.c
:
#include <stdio.h>
void callMeFromC(void);
void callMeFromHaskell(void)
{
printf("callMeFromHaskell\n");
callMeFromC();
}
Run Code Online (Sandbox Code Playgroud)
FFIFun/Foo.hs
:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module FFIFun.Foo where
import qualified Data.ByteString.Char8 as B
foreign import ccall "callMeFromHaskell"
callMeFromHaskell :: IO ()
foreign export ccall callMeFromC :: IO ()
callMeFromC …
Run Code Online (Sandbox Code Playgroud) 关于Haskell中的FFI和GHC的交互模式我有一个问题.
(来源也可以通过要点获得):
FFISo.hs:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
import qualified Data.ByteString.Char8 as B
foreign import ccall "callMeFromHaskell"
callMeFromHaskell :: IO ()
foreign export ccall callMeFromC :: IO ()
callMeFromC :: IO ()
callMeFromC = B.putStrLn "callMeFromC"
main :: IO ()
main = do
B.putStrLn "main"
callMeFromHaskell
return ()
Run Code Online (Sandbox Code Playgroud)
抄送:
#include <stdio.h>
void callMeFromC(void);
void callMeFromHaskell(void)
{
printf("callMeFromHaskell\n");
callMeFromC();
}
Run Code Online (Sandbox Code Playgroud)
Makefile文件:
GHC_OPT := -Wall -O2 -fno-warn-unused-do-bind
all: ffiso
test: ffiso
./$<
ffiso: FFISo.hs …
Run Code Online (Sandbox Code Playgroud) 我哈巴狗10.04更新了我的显影机从Ubuntu的Ubuntu的LTS 12.04(或ghc 6.12.1
到ghc 7.4.1
)和我在均流项目碰到一个很奇怪的行为.
几个小时后,我把它减少到以下代码:
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
import Data.Word
import Text.Printf
import Foreign
foreign import ccall "dynamic"
code_void :: FunPtr (IO ()) -> (IO ())
main :: IO ()
main = do
entryPtr <- (mallocBytes 2)
poke entryPtr (0xc390 :: Word16) -- nop (0x90); ret(0xc3) (little endian order)
_ <- printf "entry point: 0x%08x\n" ((fromIntegral $ ptrToIntPtr entryPtr) :: Int)
_ <- getLine -- for debugging
code_void $ castPtrToFunPtr entryPtr
putStrLn …
Run Code Online (Sandbox Code Playgroud) 我实现了一个小函数bruteforce
,使用惰性求值来找到问题的第一个有效解决方案:
import Data.Maybe
bruteforce :: (a -> Bool) -> [a] -> Maybe a
bruteforce f xs
| null result = Nothing
| otherwise = Just $ head result
where
result = mapMaybe bruteforce' xs
-- test one instance
bruteforce' x
| f x = Just x
| otherwise = Nothing
generatorString :: Int -> [String]
generatorString 0 = [""]
generatorString deep = concatMap (\x -> map (\ys -> (x:ys)) nextgen) ['a'..'z']
where nextgen = generatorString (deep - 1) …
Run Code Online (Sandbox Code Playgroud) 我想定义一个记录器功能,例如
myPutStrLn = putStrLn . (++) "log: "
main = do myPutStrLn "hello"
Run Code Online (Sandbox Code Playgroud)
很好 现在,我想格式化与所提供的字符串printf
,这样
myPutStrLn $ printf "test %d" (23 :: Int)
Run Code Online (Sandbox Code Playgroud)
大!由于我经常使用这种模式,因此我想将其printf
纳入记录器功能:
myPrintf = logger . printf
where
-- note, this is just an example. should be
-- replaceable with any function with this
-- typesignature
logger :: String -> IO ()
logger = putStrLn . (++) "log: "
main = myPrintf "test %d" (23 :: Int)
Run Code Online (Sandbox Code Playgroud)
不幸的是,这失败了
The function `myPrintf' is applied to …
Run Code Online (Sandbox Code Playgroud) 有一个相当低级别的应用程序,我进入一个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"
Run Code Online (Sandbox Code Playgroud)
ffi.c:
void func(void);
unsigned long getFuncAddr(void)
{
return (unsigned long) func;
}
Run Code Online (Sandbox Code Playgroud)
Makefile文件:
all: main
./$<
objdump -D $< | grep '<func>'
main: main.hs ffi.c
ghc --make …
Run Code Online (Sandbox Code Playgroud) haskell ×6
ffi ×4
ghc ×4
ghci ×2
binary ×1
brute-force ×1
linker ×1
linux ×1
polyvariadic ×1
printf ×1