【问题标题】:How I can convert haskell [char] to CString如何将 haskell [char] 转换为 CString
【发布时间】:2020-04-11 14:38:39
【问题描述】:

我在 haskell 中的代码有一些错误: 无法将类型“[Char]”与“Ptr CChar”匹配 预期类型:CString 实际类型:[Char]

源代码:

{-# LANGUAGE ForeignFunctionInterface #-}
module Main where

import Foreign.C -- get the C types
import Foreign.Ptr (Ptr,nullPtr)
import Foreign.C.String

foreign import ccall "stdio.h printf"
  myprintf :: CString -> IO CString

main = do
  myprintf "hello"

【问题讨论】:

  • 为什么是"stdio.h printf" 而不是"printf"
  • 在一些例子中我看到了这种做法

标签: c haskell


【解决方案1】:

文字"hello"String 类型(也称为[Char]),而不是CString 类型,所以你不能将它传递给myprintf。类型不匹配。

您可以通过newCString function 将其转换为CString

main = do
    str <- newCString "hello"
    myprintf str

或者以更紧凑的方式:

main =
    myprintf =<< newCString "hello"

在相关说明中,我认为您导入的签名不正确。来自stdio 的函数printf 不返回字符串,而是返回int

由于您只是丢弃返回值,这没什么大不了的(或者是吗?不确定 FFI 在这里如何工作),但是如果您在假设它是 CString 的同时尝试实际使用它,则无法预测坏事可能会发生。

【讨论】:

  • printf 在 C 中是一个可变参数函数,我不确定我们是否可以如此轻松地导入它而忽略参数的可变参数部分。也许我们可以使用ccall。此外,我认为必须手动释放 CString (?)
  • 可惜Cstring 是一个类型别名,所以你不能为它定义一个IsString 实例。
  • @chepner 可以为别名创建实例(毕竟String本身也有实例),问题是String转换为CString不是纯操作。
  • @FyodorSoikin 啊,对。我对别名类型已经有实例的情况感到困惑,在这种情况下,别名不足以创建单独的实例。
猜你喜欢
  • 2012-09-17
  • 2015-08-07
  • 2020-06-12
  • 2010-10-25
  • 1970-01-01
  • 2012-11-07
  • 2015-05-14
  • 1970-01-01
相关资源
最近更新 更多