2011-05-19 61 views
7

我需要一個示例演示如何使用hsc2hs,我認爲,當我寫這樣一個頭文件:如何使用hsc2hs綁定常量,函數和數據結構?

// foo.h 
#define PI 3.14159 

typedef struct { 
    int i1; 
    int i2; 
} foo; 

struct foo2 { 
    int i1; 
    int i2; 
}; 

int fooFkt(foo f); 

,然後創建一個HSC文件:

import Foreign 
import Foreign.C 

#include "foo.h" 

使用hsc2hs

{-# INCLUDE "foo.h" #-} 
{-# LINE 1 "test.hsc" #-} 
import Foreign 
{-# LINE 2 "test.hsc" #-} 
import Foreign.C 


{-# LINE 5 "test.hsc" #-} 

我不明白,我以爲帽子hsc2hs會爲我輸入所有需要的東西,比如PI

誰能給我一個更好的例子?

回答

8

繼RWH ch 17,您需要引入一些將C PI值綁定到Haskell中的符號的東西。

例如:

{-# LANGUAGE ForeignFunctionInterface #-} 
{-# LANGUAGE CPP      #-} 

import Foreign 
import Foreign.C 

-- helpers 
import Control.Applicative 
import Control.Monad 

#include "foo.h" 

-- binding a symbol 

-- Note that hsc2hs can't marshal floating point CPP values, so this will be "3" 
-- c_pi :: CInt 
-- c_pi = #const PI 

-- Instead, bind to a function that returns a CFloat 
pi' :: Float 
pi' = realToFrac c_pi 

foreign import ccall unsafe "my_pi" c_pi :: CFloat 

雖然我們在這裏,我們也可以在封結構,並從哈斯克爾:

-- Marshalling for the struct foo 

data Foo = Foo { i1, i2 :: Int } 
    deriving Show 

-- Define how to marshal foo structs 

instance Storable Foo where 
    sizeOf _ = #{size foo} 

    alignment _ = alignment (undefined :: CInt) 

    poke p foo = do 
     #{poke foo, i1} p $ i1 foo 
     #{poke foo, i2} p $ i2 foo 

    peek p = return Foo 
       `ap` (#{peek foo, i1} p) 
       `ap` (#{peek foo, i2} p) 

並綁定到fooFkt功能:

-- Import the function too 

foreign import ccall "foo.h fooFkt" 
    c_fooFkt :: Ptr Foo -> IO CInt 

-- Marshal data to and from C 

fooFkt :: Foo -> IO Int 
fooFkt f = fromIntegral <$> with f c_fooFkt 

完成。

+2

不綁定 - dsl提供了一些float常量#defines? #分數或類似的東西? – aleator 2011-05-19 19:16:07

+2

綁定-DSL爲您提供了一些其他非常有用的東西。我強烈建議:https://bitbucket.org/mauricio/bindings-dsl/wiki/DetailedUsageGuide – sclv 2011-05-19 19:41:42

2

它的工作原理,如果你確實使用了一些定義從foo.h

import Foreign 
import Foreign.C 

#include "foo.h" 

pi = #const PI 

{-# INCLUDE "foo.h" #-} 
{-# LINE 1 "test.hsc" #-} 
import Foreign 
{-# LINE 2 "test.hsc" #-} 
import Foreign.C 


{-# LINE 5 "test.hsc" #-} 

pi = 3 
{-# LINE 7 "test.hsc" #-} 

下面是來自網絡包一個真實的世界用法示例:https://github.com/haskell/network/blob/master/Network/Socket/ByteString/MsgHdr.hsc

+0

我該如何與結構做到這一點? – ewggwegw 2011-05-19 11:14:36

+0

pi = 3?這是一些浮動常數問題? – aleator 2011-05-19 11:22:26

+4

@aleator hsc2hs只能[編組字符串和整數#defines](http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/hsc2hs.html)。 – 2011-05-19 18:26:38