Seeking advice on best practices with FFI

View: New views
2 Messages — Rating Filter:   Alert me  

Seeking advice on best practices with FFI

by PJ Durai :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

I am trying to write FFI wrappers for a dynamic library in windows.
I would like to get some help in how to go about doing things.

For example for this C function, the import and wrapper I came up with
are listed below.

-- STATUS LNPUBLIC NSFDbOpen (char far *PathName, DBHANDLE far *rethDB);


foreign import stdcall "nsfdb.h NSFDbOpen" nsfDbOpen' ::CString -> Ptr
CInt -> IO CInt

type DbHandle = CInt

nsfDbOpen :: String -> IO DbHandle
nsfDbOpen dbname = alloca $ \ptr -> do
                     db <- newCString dbname
                     rc <- nsfDbOpen' db ptr
                     handle <- peek ptr
                     if rc /= 0 then error "dbopen failed" else return handle

Q: Does that look ok?  Is the db <- newCString leaking ?


Q:  How would I import and call a function with signature like this

calling C code:

char str1[MAX_PATH];
char str2[MAX_PATH];

GetStringValues( str1, str2);

called C function signature is:
void  GetStringValues( char* s1, char* s2);

i.e. how would the haskell import (and the wrapper function) look like
in situation like this (where I have to pass preallocated char array
to C code and get it filled up)?


Appreciate your time.
thanks
pj
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Seeking advice on best practices with FFI

by Bulat Ziganshin-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello PJ,

Saturday, May 10, 2008, 1:45:29 AM, you wrote:

> Q: Does that look ok?  Is the db <- newCString leaking ?

yes. use withCString instead

> void  GetStringValues( char* s1, char* s2);

if this functions fills s1 and s2, use alloca and peekCString

one example of (rather generic) wrapper for C functions that accepts
string (c_method) and returns string (c_out_method):

generalDoWithMethod mType c_action method = do
  withCString method $ \c_method -> do
    allocaBytes aMAX_METHOD_STRLEN $ \c_out_method -> do
      ret <- c_action c_method c_out_method
      case ret of
        0 -> peekCString c_out_method
        _ -> fail$ "Unsupported "++mType++" method or error in parameters: "++method


--
Best regards,
 Bulat                            mailto:Bulat.Ziganshin@...

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe