How to pass a string from Haskell to C?

c, ffi, haskell

Solution

You want a `CString`.

Going from `CString` to `String`:

peekCString :: CString -> IO String

Going from `String` to `CString`:

withCString :: String -> (CString -> IO a) -> IO a

There's also Haddock documentation for module `Foreign.C.String`.

The general list of types that can be used in `foreign` declarations is specified as part of the Foreign Function Interface in the Haskell Report.

Edit

Ok, here's a very small example of a thing you can do, somewhat based on your sample code. Create a Haskell file `CTest.hs` with the following contents:

module CTest where

import Foreign.C

hello :: IO CString
hello = newCString "hello"

foreign export ccall hello :: IO CString

Then create a C file `ctest.c` with the following contents:

#include <stdio.h>
#include "CTest_stub.h"

int main (int argc, char *argv[]) {
  hs_init(&argc, &argv);
  printf("%s\n", hello());
  hs_exit();
  return 0;
}

Then compile and run as follows:

$ ghc CTest
[1 of 1] Compiling CTest            ( CTest.hs, CTest.o )
$ ghc -o ctest ctest.c CTest.o -no-hs-main
$ ./ctest
hello

Problem

All I want to do is pass a plain-text string from Haskell to C. However, it says that [Char] is an unacceptable return type. I can't find anywhere why they think it is, nor what acceptable return types are. I'm trying to make a very simple OS image that I can boot with Qemu. Does anyone know how to do this? Thanks. ``` {-# LANGUAGE ForeignFunctionInterface #-} module Hello where import Foreign import Foreign.C.String import Foreign.C.Types hello :: String -> (CString -> IO a) -> IO a hello = "Hello, world!" foreign export ccall hello :: String -> (CString -> IO a) -> IO a ```

Original source