[Haskell-beginners] Improve my FFI code please...
Sean Charles
sean at objitsu.com
Fri Jan 21 00:35:02 CET 2011
Hi list,
I am *still* cursing the fact that I like where Haskell is taking me but
that I am too dumb to get it into my head as quickly as I'd like!
I will not give up and in that vein I have been beating myself up trying
to run before I can walk as usual by attempting to write an FFI wrapper
around the Ubuntu libcwiimote library!
Having been inspired by johnnylee.net and having found his code is for
Windows and C# I have taken it on myself to reproduce what he's done but
using Haskell and OpenGL. Laugh, I nearly cried because it's taken hours
of frustration just to get this far! I've built the hardware and now I
need the software as usual.
So, here we go... what I post here is the beginnings of a Wiimote
wrapper. I *think* I understand Monads properly now, Brian Beck video on
C9 (MSDN) really really helped a lot, I'd recommend that to anybody
still struggling with the concept.
What I want to know is can my code be improved by using monadic chaining
and if so, with what and how (LMAO) and also have I overlooked or
otherwise not used the correct forms, idioms etc. to achieve what I have
so far ? I am really keen to know how the real gurus out there could
reduce this code down or make it 'more haskell like'.
Basically, I want you to correct it, improve it, show me and others how
to do it right! I want it de-constructed, ripped to pieces, laughed at,
openly mocked and I will learn from it and enjoy it because I am a
developer! ;) LOL
It compiles with ...
ghc --make -lcwiimote -o wmscan WiiMote.hs
and runs like so ...
sean at sean-desktop:~/Documents/bluetooth$ ./wmscan 00:21:BD:A3:97:C7
Connecting to 00:21:BD:A3:97:C7
00:21:BD:A3:97:C7connected OK, disconnecting ...OK
sean at sean-desktop:~/Documents/bluetooth$
...and I was proud as hell, almost as proud as watching my son born but
without the goo.
Many thanks.
Sean
----
{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign
import Foreign.C.Types
import Foreign.Ptr
import Foreign.C.String
import System
#include "wiimote_api.h"
foreign import ccall unsafe "wiimote_api.h wiimote_open"
c_wiimote_open :: CString -> IO (Ptr Word8)
foreign import ccall unsafe "wiimote_api.h wiimote_close"
c_wiimote_close :: (Ptr Word8) -> IO CInt
wiiOpen :: String -> IO (Maybe (Ptr Word8))
wiiOpen wid = do
handle <- withCString wid c_wiimote_open
case handle of
nullPtr -> return Nothing
handle -> return (Just handle)
wiiClose :: Ptr Word8 -> IO Bool
wiiClose wptr = do
response <- c_wiimote_close wptr
case response of
0 -> return True
_ -> return False
-- Open the wiiremote, print the handle and close it
test :: String -> IO ()
test wiiHID = do
wiimote <- wiiOpen wiiHID
case wiimote of
Just handle -> do
putStr (wiiHID ++ " connected OK, disconnecting ... ")
status <- wiiClose handle
case status of
True -> putStrLn "OK"
False -> putStrLn "FAIL"
Nothing -> putStrLn "FAIL"
return ()
-- expects a single HID string on the command line ...
main :: IO ()
main = do
args <- getArgs
case args of
[hid] -> do
putStrLn ("Connecting to " ++ hid)
test hid
_ -> putStrLn "Supply ONE Wiimote HID address!"
More information about the Beginners
mailing list