-
Notifications
You must be signed in to change notification settings - Fork 1
/
Test.hs
137 lines (104 loc) · 3.08 KB
/
Test.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
-- From: http://weblog.haskell.cz/pivnik/building-a-shared-library-in-haskell/
-- Parts cribbed from: http://stackoverflow.com/questions/4502115/interchange-structured-data-between-haskell-and-c
{-# LANGUAGE ForeignFunctionInterface #-}
module Test where
import Foreign.C.Types
import Foreign.C.String
import Foreign.StablePtr
import Foreign.Storable
import Foreign.Marshal.Alloc
import Foreign.Marshal.Array
import Foreign.Ptr
-- Very simple haskell function
hsfun :: CInt -> IO CInt
hsfun x = do
putStrLn "Hello World"
return (42 + x)
foreign export ccall
hsfun :: CInt -> IO CInt
-- Wrapping up a Haskell object (and then unrwapping it )
data Wrapper = Wrap CInt
wrap :: CInt -> IO (StablePtr Wrapper)
wrap x = newStablePtr $ Wrap x
unwrap :: StablePtr Wrapper -> IO CInt
unwrap wrapped = do
Wrap d <- deRefStablePtr wrapped
return d
foreign export ccall
wrap :: CInt -> IO (StablePtr Wrapper)
foreign export ccall
unwrap :: StablePtr Wrapper -> IO CInt
-- Writing to memory
data ExampleStruct = ExampleStruct Int Int deriving (Eq, Show)
instance Storable ExampleStruct where
alignment _ = alignment (undefined :: CDouble)
sizeOf _ = 8
peek p = do
x <- peekByteOff p 0 ::IO CInt
y <- peekByteOff p 4 ::IO CInt
return $ ExampleStruct (fromIntegral x) (fromIntegral y)
poke p (ExampleStruct x y) = do
_x <- return x
_y <- return y
pokeByteOff p 0 _x
pokeByteOff p 4 _y
gethsstruct :: CInt -> CInt -> IO (Ptr ExampleStruct)
gethsstruct x y = do
let e = ExampleStruct (fromIntegral x) (fromIntegral y)
p <- malloc
poke p e
return p
freehsstruct :: (Ptr ExampleStruct) -> IO ()
freehsstruct = free
getx :: (Ptr ExampleStruct) -> IO CInt
getx e = do
(ExampleStruct x _) <- peek e
return $ fromIntegral x
foreign export ccall
gethsstruct :: CInt -> CInt -> IO (Ptr ExampleStruct)
foreign export ccall
getx :: (Ptr ExampleStruct) -> IO CInt
foreign export ccall
freehsstruct :: (Ptr ExampleStruct) -> IO ()
-- Convert array to list
gethslist :: IO (Ptr ExampleStruct)
gethslist = do
let e = ExampleStruct (fromIntegral 10) (fromIntegral 30)
let e10 = [e, e, e, e, e, e, e, e, e, e]
p <- mallocArray 10
pokeArray p e10
return p
printlist :: (Ptr ExampleStruct) -> IO ()
printlist lst_e = do
es <- peekArray 10 lst_e
putStr "Blah: "
putStr $ show es
putStr "\n"
foreign export ccall
gethslist :: IO (Ptr ExampleStruct)
foreign export ccall
printlist :: (Ptr ExampleStruct) -> IO ()
-- Some string handling
hsstrlen :: CString -> IO CInt
hsstrlen str = do
s <- peekCString str
return $ fromIntegral $ length s
gethsstr :: IO CString
gethsstr = do
newCString "hello world"
foreign export ccall
hsstrlen :: CString -> IO CInt
foreign export ccall
gethsstr :: IO CString
-- Something more substrantional
wc :: String -> IO Int
wc file = do
contents <- readFile file
return $ length $ words $ contents
export_wc :: CString -> IO CInt
export_wc file = do
_file <- peekCString file
_count <- wc _file
return $ fromIntegral $ _count
foreign export ccall
export_wc ::CString -> IO CInt