Haskell 如何在 Windows 上调用 ffi

Haskell how to call ffi on Windows

抱歉,这是一个新手问题。我正在尝试从 Haskell 调用 C 函数。我目前正在 Windows 上使用堆栈。我从以下运行良好的简单示例开始:

import Prelude hiding (sin)
 
import Foreign.C -- get the C types
 
-- pure function
foreign import ccall "sin" c_sin :: CDouble -> CDouble

sin :: Double -> Double
sin d = realToFrac (c_sin (realToFrac d))

main = do
    print . sin =<< readLn

然后我尝试添加另一个自定义 myfunc 函数:

{-# INCLUDE "myfunction.h" #-}
{-# LANGUAGE ForeignFunctionInterface #-}

import Prelude hiding (sin)
 
import Foreign.C -- get the C types
 
-- pure function
foreign import ccall "sin" c_sin :: CDouble -> CDouble
foreign import ccall "myfunc" c_myfunction :: Double -> Double

sin :: Double -> Double
sin d = realToFrac (c_sin (realToFrac d))

myfunc :: Double -> Double
myfunc d = realToFrac(c_myfunction d)

main = do
   print . sin =<< readLn
   print . myfunc =<< readLn

我收到以下错误:

src\Main.hs:1:12: warning:
    -#include and INCLUDE pragmas are deprecated: They no longer have any effect
Linking src\Main.exe ...
src\Main.o:fake:(.text+0x56): undefined reference to `myfunc'
collect2.exe: error: ld returned 1 exit status
`gcc.exe' failed in phase `Linker'. (Exit code: 1)

我已经在 myfunction.c 中将 myfunc 定义为一个常规的 c 函数,对应 header myfunction.h.

为了编译我正在使用的应用程序 stack ghc src/Main.hs src/myfunction.c

我的所有资源都位于我项目的 src 目录下。

好的,终于弄明白了,这是更新后的代码:

{-# INCLUDE "myfunction.h" #-}

{-# LANGUAGE ForeignFunctionInterface #-}


import Prelude hiding (sin)
 
import Foreign.C -- get the C types
 
-- pure function
foreign import ccall "sin" c_sin :: CDouble -> CDouble
foreign import ccall "myfunction" c_myfunction :: Double -> Double

sin :: Double -> Double
sin d = realToFrac (c_sin (realToFrac d))

myfunction :: Double -> Double
myfunction d = realToFrac(c_myfunction d)

main = do
  print . sin =<< readLn
  print . myfunction =<< readLn

您还需要确保在外部导入指令中使用 c_ 引用您的 c 函数。所以对于 c 函数 foo,它应该被引用为 c_myfoo。最后编译使用 stack ghc Main.hs myfunction.c