2016-12-03 48 views
1

對不起,如果這是一個新手問題。我試圖從Haskell調用一個C函數。我目前在Windows上使用堆棧。我開始用下面簡單的例子,效果很好:Haskell如何在Windows上調用ffi

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) 

我已將myfunc定義爲myfunction.c中的常規c函數,其中對應標題爲myfunction.h

要編譯應用程序我使用stack ghc src/Main.hs src/myfunction.c

的我的消息來源所有位於src目錄我的項目之下。

回答

1

好吧終於想通了,這裏是更新後的代碼:

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

你也需要確保在國外import指令與c_引用您的C函數。所以對於c函數foo它應該被引用爲c_myfoo。最後編譯使用stack ghc Main.hs myfunction.c