简体   繁体   English

动态加载已编译的Haskell模块 - GHC 7.6

[英]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. 你想要的是加载它,就像你使用:moduleimport声明,它与编译模块一起使用。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM