Создание интерпретатора haskell (подсказки) в виде динамической библиотеки, используемой в C ++: отсутствует Interpreter.dyn_hi - PullRequest
3 голосов
/ 02 января 2012

Я хочу создать интерпретатор haskell, который я могу использовать из C ++ в Linux.

У меня есть файл FFIInterpreter.hs, который реализует интерпретатор в haskell и экспортирует функции через FFI в C ++.

module FFIInterpreter where

import Language.Haskell.Interpreter

import Data.IORef
import Foreign.StablePtr
import Foreign.C.Types
import Foreign.C.String
import Control.Monad
import Foreign.Marshal.Alloc

type Session = Interpreter ()
type Context = StablePtr (IORef Session)

foreign export ccall createContext :: CString -> IO Context
createContext :: CString -> IO Context
createContext name = join ((liftM doCreateContext) (peekCString name))
  where
    doCreateContext :: ModuleName -> IO Context
    doCreateContext name 
      = do let session = newModule name 
           _ <- runInterpreter session
           liftIO $ newStablePtr =<< newIORef session

newModule :: ModuleName -> Session
newModule name = loadModules [name] >> setTopLevelModules [name]

foreign export ccall freeContext :: Context -> IO ()
freeContext :: Context -> IO ()
freeContext = freeStablePtr

foreign export ccall runExpr :: Context -> CString -> IO CString
runExpr :: Context -> CString -> IO CString
runExpr env input = join ((liftM newCString) (join (((liftM liftM) doRunExpr) env (peekCString input))))
  where
    doRunExpr :: Context -> String -> IO String
    doRunExpr env input
      = do env_value <- deRefStablePtr env
           tcs_value <- readIORef env_value
           result    <- runInterpreter (tcs_value >> eval input)
           return $ either show id result

foreign export ccall freeString :: CString -> IO ()
freeString :: CString -> IO ()
freeString = Foreign.Marshal.Alloc.free

Когда я компилирую весь проект с помощью ghc, все работает нормально.Я использую следующую команду:

ghc -no-hs-main FFIInterpreter.hs main.cpp -lstdc++

Но модуль haskell является лишь небольшим фрагментом проекта C ++, и я не хочу, чтобы весь проект зависел от ghc.

Так что яхочу создать динамическую библиотеку с помощью ghc, а затем связать ее с проектом, используя g ++.

$ ghc -shared -fPIC FFIInterpreter.hs module_init.c -lstdc++
[1 of 1] Compiling FFIInterpreter   ( FFIInterpreter.hs, FFIInterpreter.o )
Linking a.out ...
/usr/bin/ld: /usr/lib/haskell-packages/ghc/lib/hint-0.3.3.2/ghc-7.0.3/libHShint-0.3.3.2.a(Interpreter.o): relocation R_X86_64_32S against `.data' can not be used when making a shared object; recompile with -fPIC
/usr/lib/haskell-packages/ghc/lib/hint-0.3.3.2/ghc-7.0.3/libHShint-0.3.3.2.a: could not read symbols: Bad value
collect2: ld gab 1 als Ende-Status zurück

Поэтому я добавил ключевое слово -dynamic, но оно также не работает:

$ ghc -dynamic -shared -fPIC FFIInterpreter.hs librarymain.cpp -lstdc++
FFIInterpreter.hs:3:8:
    Could not find module `Language.Haskell.Interpreter':
      Perhaps you haven't installed the "dyn" libraries for package `hint-0.3.3.2'?
      Use -v to see a list of the files searched for.

Я искал в моей системе файл Interpreter.dyn_hi, но не нашел его.Есть ли способ получить это?Я также пытался установить подсказку вручную, но это также не доставляет файл Interpreter.dyn_hi.

1 Ответ

3 голосов
/ 02 января 2012

Вы должны установить библиотеку (и все, от чего это зависит) с флагом --enable-shared (используя cabal-install), чтобы получить файлы .dyn_hi и .dyn_o.Вы можете установить эту опцию в файле ~/.cabal/config.

Возможно, самый простой способ - раскомментировать строку shared: XXX в ~/.cabal/config, установить для параметра True и

cabal install --reinstall world

В целях безопасности сначала запустите его с опцией --dry-run, чтобы выявить проблемы на ранней стадии.Если вывод --dry-run выглядит приемлемым, продолжайте и переустановите - хотя это займет некоторое время.

...