Actually, what I need to do is a fair bit more complex than string marshalling.  It feels like I'll need to pull together a number of different concepts so I may as well describe the problem directly.

The C function I want to call is StartServiceCtrlDispatcher:

BOOL StartServiceCtrlDispatcher(
const LPSERVICE_TABLE_ENTRY lpServiceTable
);
It takes an array of SERVICE_TABLE_ENTRY structures:

typedef struct _SERVICE_TABLE_ENTRY {
LPTSTR lpServiceName;
LPSERVICE_MAIN_FUNCTION lpServiceProc;
} SERVICE_TABLE_ENTRY,
*LPSERVICE_TABLE_ENTRY;
The typedef  LPSERVICE_MAIN_FUNCTION is something like:
typedef (VOID WINAPI
 ServiceMain)(
DWORD dwArgc,
LPTSTR* lpszArgv
);
It seems to me that I'll need to learn how to do the following:

* Represent SERVICE_TABLE_ENTRY AND LPSERVICE_TABLE_ENTRY structs as a haskell type.
* Create an array of SERVICE_TABLE_ENTRY structs.
* Populate the array (they're null terminated).
* Do all sorts of elaborate marshalling so that the end product is a sensibly typed Haskell function like this:

data ServiceTableEntry = ServiceTableEntry {
  serviceName :: String
  serviceProc :: [String] -> IO ()
  }
startServiceCtrlDispatcher :: [ServiceTableEntry] -> IO ()

That's quite a lot to chew on and I finding it challenging learning about all these things and combining them at the same time.

I've attached the complete source to what I have so far in a zip file.

Thanks

-John

On 2/6/07, Stefan O'Rear < stefanor@cox.net> wrote:
On Tue, Feb 06, 2007 at 12:40:38PM +1100, John Ky wrote:
> Hi Stefan,
>
> In that case, how do I marshall [String] to Ptr (Ptr CChar)?

look at Foreign.C.String and Foreign.Ptr