繁体   English   中英

如何将字符串从 Haskell 传递给 C?

[英]How to pass a string from Haskell to C?

我想要做的就是将一个纯文本字符串从 Haskell 传递给 C。但是,它说 [Char] 是一种不可接受的返回类型。 我找不到他们认为的任何原因,也找不到可接受的返回类型。

我正在尝试制作一个可以使用 Qemu 启动的非常简单的操作系统映像。

有谁知道如何做到这一点? 谢谢。

    {-# 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

你想要一个CString

CStringString

peekCString :: CString -> IO String

StringCString

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

还有模块Foreign.C.String Haddock 文档。

可以在foreign声明中使用的类型的一般列表在 Haskell 报告中指定为外部函数接口的一部分。

编辑

好的,这是您可以做的事情的一个很小的例子,有点基于您的示例代码。 使用以下内容创建 Haskell 文件CTest.hs

module CTest where

import Foreign.C

hello :: IO CString
hello = newCString "hello"

foreign export ccall hello :: IO CString

然后创建一个包含以下内容的 C 文件ctest.c

#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;
}

然后编译运行如下:

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

我认为你需要的是System.IO.Unsafe.unsafePerformIO在将 CString 发送到 C 之前将 IO CString 转换为 CString。newCString 会将 Haskell 字符串转换为 IO CString。 因此System.IO.Unsafe.unsafePerformIO $ newCString a可以传递给您的 C 例程,该例程将接受char*类型的输入。 如果你的 C 例程返回 static char*那么System.IO.Unsafe.unsafePerformIO $ peekCString会给你一个 Haskell 字符串。 您需要导入System.IO.Unsafe unsafePerformIOForeign.C.String (或Foreign.C.Types ?)中有一个已弃用的实现,因此您必须使用完整路径。 在我找到unsafePerformIO之前,我unsafePerformIOunsafePerformIO ——可能是因为人们对某些危险的东西过敏,以至于强制声明不纯为纯。 newCString如果不清理就重复使用会导致内存泄漏。 withCString可能是更好的选择 - 稍后会学习。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM