为什么GHCi无法加载指定的分片库?

时间:2016-11-14 08:50:36

标签: haskell ghci

我在Mac OS中的/ usr / local / lib /下安装了库gsl(libgsl.dylib),并希望从Haskell调用库函数。但是我没有使用GHCi但是使用GHC成功了。

在GHCi中:

stack ghci --ghci-options="Bessel.hs -lgsl"
> besselJn 0 10
dyld: lazy symbol binding failed: Symbol not found: _gsl_sf_bessel_J0_e
  Referenced from: libgsl.dylib
  Expected in: flat namespace

dyld: Symbol not found: _gsl_sf_bessel_J0_e
  Referenced from: libgsl.dylib
  Expected in: flat namespace

在GHC中:

 stack ghc -- Bessel-main.hs -lgsl
 ./Bessel-main  (which is succeed)

Bessel.hs是一个包导出函数besselJnBessel-main.hs只是要调用的主模块。

我使用GHCi的方式有什么不对吗?很奇怪,GHC可以成功编译/链接共享库并运行,但GHCi不能。

添加更多信息。 Bessel.hs使用命令Bessel.hsc生成hsc2hs Bessel.hsc(应首先使用stack install hsc2hs安装hsc2hs)。以下是

Bessel.hsc

{-# LANGUAGE ForeignFunctionInterface #-}

module Bessel (besselJn) where

import Foreign
import Foreign.Ptr
import Foreign.C.String
import Foreign.C.Types
import System.IO.Unsafe

#include <gsl/gsl_sf_result.h>

data GslSfResult = GslSfResult { gsl_value :: CDouble, gsl_error :: CDouble }

instance Storable GslSfResult where
    sizeOf    _ = (#size gsl_sf_result)
    alignment _ = alignment (undefined :: CDouble)
    peek ptr = do
        value <- (#peek gsl_sf_result, val) ptr
        error <- (#peek gsl_sf_result, err) ptr
        return  GslSfResult { gsl_value = value, gsl_error = error }
    poke ptr (GslSfResult value error) = do
        (#poke gsl_sf_result, val) ptr value
        (#poke gsl_sf_result, err) ptr error


foreign import ccall unsafe "gsl/gsl_sf_bessel.h gsl_sf_bessel_Jn_e"
     c_besselJn :: CInt -> CDouble -> Ptr GslSfResult -> IO CInt

foreign import ccall unsafe "gsl/gsl_errno.h gsl_set_error_handler_off"
     c_deactivate_gsl_error_handler :: IO ()

foreign import ccall unsafe "gsl/gsl_errno.h gsl_strerror"
     c_error_string :: CInt -> IO CString

besselJn :: Int -> Double -> Either String (Double, Double)
besselJn n x = unsafePerformIO $
    alloca $ \gslSfPtr -> do
        c_deactivate_gsl_error_handler
        status <- c_besselJn (fromIntegral n) (realToFrac x) gslSfPtr
        if status == 0
            then do
                GslSfResult val err <- peek gslSfPtr
                return $ Right (realToFrac val, realToFrac err)
            else do
                error <- c_error_string status
                error_message <- peekCString error
                return $ Left ("GSL error: "++error_message)

贝塞尔main.hs

module Main where

import Bessel as B

main = do
  print $ B.besselJn  0 10

0 个答案:

没有答案