遵循此处发布的 GHC 教程,并按照我之前提出的堆栈溢出问题中的建议对此代码进行了更改,我创建了一个程序,该程序能够在 Test.hs 中编译和运行模块,并使用函数 print 打印字符串到屏幕:
import GHC
import GHC.Paths
import DynFlags
import Unsafe.Coerce
main :: IO ()
main =
defaultErrorHandler defaultLogAction $ do
func <- runGhc (Just libdir) $ do
dflags <- getSessionDynFlags
setSessionDynFlags dflags
target <- guessTarget "Test.hs" Nothing
addTarget target
r <- load LoadAllTargets
case r of
Failed -> error "Compilation failed"
Succeeded -> do
m <- findModule (mkModuleName "Test") Nothing
setContext [IIModule m]
value <- compileExpr ("Test.print")
do let value' = (unsafeCoerce value) :: String -> IO ()
return value'
func "Hello"
return ()
如评论中所述,此代码的问题在于它似乎仅在您第一次运行时才有效(当尚未编译 Test.hs 时)。如果您再次尝试运行该代码,则会出现以下错误:
mkTopLevEnv: not interpreted main:Test
我相信这与代码已经编译的事实有关。如果我删除 .hi 和 .o 文件并再次运行该程序,则该程序会以正确的输出正确运行。我错过了什么?我目前正在使用 ghc 版本 7.4.1
(注意:我尝试过查看 GHC API,但找不到对 mkTopLevEnv 的任何引用)