【问题标题】:Dynamically loading compiled Haskell module - GHC 7.6动态加载已编译的 Haskell 模块 - GHC 7.6
【发布时间】:2013-05-24 06:35:54
【问题描述】:

我正在尝试使用 GHC API 动态编译和加载 Haskell 模块。我知道 API 从一个版本到另一个版本波动很大,所以我专门谈论 GHC 7.6.*。

我尝试在 MacOS 和 Linux 上运行相同的代码。在这两种情况下,插件模块都可以正常编译,但在加载时会出现以下错误:Cannot add module Plugin to context: not interpreted

这个问题类似于this 中的问题,其中模块只有在宿主程序的同一运行中编译时才会加载。

-- 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

【问题讨论】:

    标签: haskell ghc ghc-api


    【解决方案1】:

    问题是您使用的是IIModule。这表明您希望将模块及其中的所有内容(包括未导出的内容)带入上下文。它与:load 基本相同,在 GHCi 中带有星号。正如您所注意到的,这仅适用于解释代码,因为它可以让您“查看”模块。

    但这不是你需要的。您想要的是像使用 :moduleimport 声明一样加载它,这适用于已编译的模块。为此,您可以使用IIDecl,它采用您可以使用simpleImportDecl 进行的导入声明:

    setContext [IIDecl $ simpleImportDecl (mkModuleName "Plugin")]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-28
      • 2012-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-27
      • 1970-01-01
      相关资源
      最近更新 更多