当前位置:  开发笔记 > 前端 > 正文

C的Haskell导出函数

如何解决《C的Haskell导出函数》经验,为你挑选了1个好方法。

我的代码:

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应用程序访问它.我做了foreign export 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.

如何正确导出此功能?



1> Fabian Schmi..:

实际上有两个错误:

foreign exportgetGPS函数的类型必须匹配,所以你需要从CString到CDouble的GPS包装器(使用peekCStringCDouble转换它们)

你不能使用元组作为返回参数.有多种解决方案,比如使用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)

记得打电话hs_iniths_exit使用C代码时.

推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有