Hi Chris,

apologies for the delay. Based on your explanation of what
myCfunc() is doing, your suggested IDL is almost right.
i.e., for a C prototype

  void myCfunc (int* size, char*** array);

I would give this the IDL signature

  typedef [string]char*  String;
  typedef [ref]String*   CString;
  void myCfunc ( [out]int* size,
                     [out,length_is(*size)]CString* pArray
               );

i.e., myCfunc() will allocate the string array, which
the caller will just supply a pointer for it to fill in.

Unfortunately, HDirect gets the unmarshalling of the 'pArray'
parameter wrong -- I've fixed this in my local copy, but need
to test the ramifications of that change first. My suggestion
to you for now would be to avoid using HDirect's marshalling
smarts for dependent arguments & just do the unmarshalling yourself:

   typedef [ptr]char** CStringArray;
   void myCfunc ( [out]int* size,
                        [out]CStringArray* pArray
                );

which should cause HDirect to generate a Haskell function with 
the type:

myCfunc :: Prelude.IO (Int.Int32, CStringArray)

You can then unmarshal the array using HDirect.unmarshalllist *
HDirect.readString.

hth
--sigbjorn

> -----Original Message-----
> From: Simon Peyton-Jones 
> Sent: Monday, August 21, 2000 00:53
> To: Chris Ryder
> Cc: Sigbjorn Finne; [EMAIL PROTECTED]
> Subject: RE: HDirect + String Arrays.
> 
> 
> I'm forwarding this to the FFI list in the hope that
> someone can help Chris.
> 
> Simon
> 
> | -----Original Message-----
> | From: Chris Ryder [mailto:[EMAIL PROTECTED]]
> | Sent: 11 August 2000 12:05
> | To: Simon Peyton-Jones
> | Subject: HDirect + String Arrays.
> | 
> | 
> | Hi,
> | 
> | I'm trying to call a C function from Haskell (GHC 4.04, 
> | HDirect 0.16) that
> | returns an array of strings. eg :
> | 
> | char **myCfunc(void);
> | 
> | or, perhaps :
> | 
> | void myCfunc (int* size, char*** array);
> | 
> | I have an IDL file that specifies :
> | 
> | module Thing {
> | void myCfunc([out]int* asize, [out,string,size_is(asize)] 
> | char*** arr);
> | };
> | 
> | This generates marshalling code that looks correct (its shown 
> | at the end
> | of this message) but when run, only the first string seems to 
> | be correctly
> | marshalled - all subsequent strings in the array become NULL 
> | (represented
> | as Nothing ?) The strings are definatly allocated in the C 
> | function, so
> | I'm sure it is a marshalling problem.
> | 
> | Is there something I'm missing or doing incorrectly ?
> | 
> | Many Thanks,
> | Chris Ryder.
> | 
> | --- Haskell code generated by ihc ---
> | 
> | -- Automatically generated by HaskellDirect (ihc), snapshot 300600
> | -- Created: 11:41 BST, Friday 11 August, 1900
> | -- Command line: -fhs-to-c Test.idl
> | 
> | module Thing
> |        ( doSomething
> |        ) where
> |        
> | import qualified Prelude
> | import qualified Addr (Addr, addrToInt)
> | import qualified HDirect (sizeofInt32, allocBytes, sizeofAddr, 
> |                           readInt32, readString, readunique, 
> | int32ToWord32, unmarshalllist, 
> |                           free, doThenFree)
> | import qualified GlaExts (toInt)
> | 
> | doSomething :: Prelude.IO [Prelude.Maybe Prelude.String]
> | doSomething =
> |   do
> |     asize <- HDirect.allocBytes (GlaExts.toInt HDirect.sizeofInt32)
> |     query <- HDirect.allocBytes ((GlaExts.toInt 
> | HDirect.sizeofAddr Prelude.* Addr.addrToInt asize))
> |     prim_Thing_doSomething asize query
> |     asize <- HDirect.readInt32 asize
> |     HDirect.doThenFree HDirect.free (HDirect.unmarshalllist 
> | HDirect.sizeofAddr 0 (HDirect.int32ToWord32 asize) 
> | (HDirect.readunique HDirect.readString)) query
> | 
> | foreign import  "doSomething" prim_Thing_doSomething :: 
> | Addr.Addr -> Addr.Addr -> Prelude.IO ()
> | 
> | 
> 

Reply via email to