加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C的Haskell导出函数

发布时间:2020-12-16 10:00:37 所属栏目:百科 来源:网络整理
导读:我的代码: getGPS :: String - IO (Double,Double)getGPS ip = do html - getHTML ip let ztags =Prelude.zip [0..] . filterStr . getTagText . getTags $html let nlat = Prelude.head $Prelude.map fst . Prelude.filter ((_,str) - strEq str ("Latitu
我的代码:

getGPS :: String -> IO (Double,Double)
getGPS ip = do
  html <- getHTML ip
  let ztags =Prelude.zip [0..] . filterStr . getTagText . getTags $html
  let nlat = Prelude.head $Prelude.map fst . Prelude.filter ((_,str) -> strEq str ("Latitude:" :: String)) $ztags
  let nlng = Prelude.head $Prelude.map fst . Prelude.filter ((_,str) -> strEq str ("Longitude:" :: String)) $ztags
  let lat = read (Prelude.head $Prelude.map snd . Prelude.filter ((n,_) -> n == nlat + 1) $ztags) :: Double
  let lng = read (Prelude.head $Prelude.map snd . Prelude.filter ((n,_) -> n == nlng + 1) $ztags) :: Double
  return (lat,lng)

工作正常.现在,我想通过FFI导出此功能,以便从C应用程序访问它.我做国外出口ccall getGPS :: CString – > IO(CDouble,CDouble)但这不起作用:

GPS.hs:45:1:
    Illegal foreign declaration: requires unregisterised,llvm (-fllvm) or native code generation (-fasm)
    When checking declaration:
      foreign export ccall "getGPS" getGPS
        :: CString -> IO (CDouble,CDouble)

GPS.hs:45:1:
    Unacceptable result type in foreign declaration:
      ‘(CDouble,CDouble)’ cannot be marshalled in a foreign call
    When checking declaration:
      foreign export ccall "getGPS" getGPS
        :: CString -> IO (CDouble,CDouble)

GPS.hs:45:1:
    Couldn't match type ‘Double’ with ‘CDouble’
    Expected type: CString -> IO (CDouble,CDouble)
      Actual type: String -> IO (Double,Double)
    In the expression: getGPS
    When checking declaration:
      foreign export ccall "getGPS" getGPS
        :: CString -> IO (CDouble,CDouble)
Failed,modules loaded: none.

如何正确导出此功能?

解决方法

实际上有两个错误:

>外部导出的类型和getGPS函数必须匹配,所以你需要一个从CString到CDouble的GPS包装器(使用peekCString和CDouble来转换它们)
>你不能使用元组作为返回参数.有多种解决方案,比如使用2个Ptr CDouble参数或定义结构.

所以可能的解决方案是

foreign export ccall "getGPS" getGPS' :: CString -> Ptr CDouble -> Ptr CDouble -> IO ()

getGPS' :: CString -> Ptr CDouble -> Ptr CDouble -> IO ()
getGPS' str d1 d2 = do
  (r1,r2) <- getGPS =<< peekCString str
  poke d1 (CDouble r1)
  poke d2 (CDouble r2)

记得在使用C代码时调用hs_init和hs_exit.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读