Динамическая загрузка скомпилированного модуля Haskell - GHC 7.6
Я пытаюсь динамически компилировать и загружать модули Haskell с использованием API GHC. Я понимаю, что API немного меняется от одной версии к другой, поэтому я специально говорю о GHC 7.6. *.
Я пробовал использовать тот же код в MacOS и Linux. В обоих случаях модуль Plugin компилируется отлично, но дает следующую ошибку при загрузке: Cannot add module Plugin to context: not interpreted
Проблема аналогична той, что была в этом, где модуль будет загружаться, только если он был скомпилирован в том же запуске главной программы.
-- Host.hs: compile with ghc-7.6.*
-- $ ghc -package ghc -package ghc-paths Host.hs
-- Needs Plugin.hs in the same directory.
module Main where
import GHC
import GHC.Paths ( libdir )
import DynFlags
import Unsafe.Coerce
main :: IO ()
main =
defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
result <- runGhc (Just libdir) $ do
dflags <- getSessionDynFlags
setSessionDynFlags dflags
target <- guessTarget "Plugin.hs" Nothing
setTargets [target]
r <- load LoadAllTargets
case r of
Failed -> error "Compilation failed"
Succeeded -> do
setContext [IIModule (mkModuleName "Plugin")]
result <- compileExpr ("Plugin.getInt")
let result' = unsafeCoerce result :: Int
return result'
print result
И плагин:
-- Plugin.hs
module Plugin where
getInt :: Int
getInt = 33
Ответы
Ответ 1
Проблема в том, что вы используете IIModule
. Это означает, что вы хотите принести модуль и все в нем, включая не экспортируемые материалы в контекст. Он по существу совпадает с :load
со звездочкой в GHCi. И, как вы заметили, это работает только с интерпретированным кодом, так как позволяет вам "заглянуть внутрь" модуля.
Но это не то, что вам нужно здесь. Вы хотите загрузить его, как если бы вы использовали :module
или объявление import
, которое работает с скомпилированными модулями. Для этого вы используете IIDecl
, который принимает объявление импорта, которое вы можете сделать с помощью simpleImportDecl
:
setContext [IIDecl $ simpleImportDecl (mkModuleName "Plugin")]