[英]Dynamically loading compiled Haskell module - GHC 7.6
I'm trying to dynamically compile and load Haskell modules using GHC API. 我正在尝试使用GHC API动态编译和加载Haskell模块。 I understand the API fluctuates quite a bit from on one version to another so I'm specifically talking about GHC 7.6.*.
我理解API从一个版本到另一个版本的波动很大,所以我特别谈到GHC 7.6。*。
I have tried running the same code on MacOS and Linux. 我试过在MacOS和Linux上运行相同的代码。 In both cases the Plugin module compiles fine but gives the following error on load:
Cannot add module Plugin to context: not interpreted
在这两种情况下,插件模块编译正常但在加载时出现以下错误:
Cannot add module Plugin to context: not interpreted
The problem is similar to the one in this where the module would only load if it was compiled in the same run of the host program. 问题类似于本文中的问题,只有在主机程序的同一运行中编译模块时才会加载该问题。
-- 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
And the plugin: 和插件:
-- Plugin.hs
module Plugin where
getInt :: Int
getInt = 33
The problem is that you're using IIModule
. 问题是你正在使用
IIModule
。 This indicates that you want to bring the module and everything in it, including non-exported stuff into the context. 这表示您希望将模块及其中的所有内容(包括未导出的内容)放入上下文中。 It's essentially the same as
:load
with an asterisk in GHCi. 它基本上与以下相同
:load
在GHCi中:load
星号。 And as you've noticed, this only works with interpreted code since it let's you "look inside" the module. 正如您所注意到的,这只适用于解释代码,因为它让您“查看”模块。
But that's not what you need here. 但这不是你需要的。 What you want is to load it as if you used
:module
or an import
declaration, which works with compiled modules. 你想要的是加载它,就像你使用
:module
或import
声明,它与编译模块一起使用。 For that, you use IIDecl
which takes an import declaration which you can make with simpleImportDecl
: 为此,您使用
IIDecl
这需要进口报关单,你可以做simpleImportDecl
:
setContext [IIDecl $ simpleImportDecl (mkModuleName "Plugin")]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.