| I want to pass a String to a function which is imported from C code: | foreign import "pass" prim_pass :: String -> String | The declaration above gives me an error from ghc like "String | type not | supported for imported functions". | I thought that String being [Char] should be supported | (somehow like a | definition with "newtype" keyword). | Can you tell me how can I pass strings to and from C code, as | simple as | possible (I know about HDirect, but I couldn't make it work | for me: red-hat | 7.1, ghc 5.00)? First of all, upgrade to 5.00.2, since it is significantly less buggy than 5.00. int fooble ( char* str, int n ) { fprintf(stderr, "fooble called: %s %d\n", str, n ); return 42; } import PrelByteArr import PrelPack (packString) foreign import "fooble" fooble fooble :: PackedString -> Int -> IO Int type PackedString = ByteArray Int main = do n <- fooble (packString "hello, C world") 99 putStrLn ("Returned value is " ++ show n) For more examples read the compiler sources, at fptools/ghc/compiler/ghci/Linker.lhs. J
"Julian Seward (Intl Vendor)"
| I want to pass a String to a function which is imported from C code: | foreign import "pass" prim_pass :: String -> String | The declaration above gives me an error from ghc like "String | type not | supported for imported functions". | I thought that String being [Char] should be supported | (somehow like a | definition with "newtype" keyword). | Can you tell me how can I pass strings to and from C code, as | simple as | possible (I know about HDirect, but I couldn't make it work | for me: red-hat | 7.1, ghc 5.00)?
First of all, upgrade to 5.00.2, since it is significantly less buggy than 5.00.
int fooble ( char* str, int n ) { fprintf(stderr, "fooble called: %s %d\n", str, n ); return 42; }
import PrelByteArr import PrelPack (packString)
foreign import "fooble" fooble fooble :: PackedString -> Int -> IO Int
type PackedString = ByteArray Int
main = do n <- fooble (packString "hello, C world") 99 putStrLn ("Returned value is " ++ show n)
For more examples read the compiler sources, at fptools/ghc/compiler/ghci/Linker.lhs.
Actually, the portable way of achieving the same effect with the new FFI libraries is import Foreign import CForeign foreign import fooble :: CString -> Int -> IO Int main = withCStringLen "hello, C world" $ \(strPtr, strLen) -> do n <- fooble strPtr strLen putStrLn ("Returned value is " ++ show n) Note that it is not really necessary to pass the length information explicitly. The CString will be NUL terminated and so directly usable by C. I just wanted to exactly imitate the cited example. If you don't need the string length, the simpler function `withCString' is sufficient. To marshall a string from C to Haskell land, use the function `CForeign.peekCString'. See http://haskell.cs.yale.edu/ghc/docs/latest/set/sec-foreign.html http://haskell.cs.yale.edu/ghc/docs/latest/set/sec-cforeign.html for details. The principal advantage of using Foreign and CForeign instead of the Prel* functions is that the former are part of the Haskell FFI standard that we are working at and so, for example, are also supported by NHC. Cheers, Manuel
participants (2)
-
Julian Seward (Intl Vendor) -
Manuel M. T. Chakravarty