簡體   English   中英

GHC API - 如何使用GHC 7.2從已編譯的模塊動態加載Haskell代碼?

[英]GHC API - How to dynamically load Haskell code from a compiled module using GHC 7.2?

我有一個現有的Haskell函數,它使用GHC API動態加載模塊中的編譯代碼。 它基於Haskell博客文章動態編譯和模塊加載的代碼。

代碼在GHC 7.0中運行良好,但必須稍加修改才能在GHC 7.2中編譯,因為GHC API發生了變化。

代碼現在在GHC 7.2中引發運行時錯誤:

mkTopLevEnv: not a home module (module name):(function name)

代碼是

evalfuncLoadFFI String moduleName, 
                String externalFuncName, 
                String internalFuncName = do

  result <- liftIO $ defaultRunGhc $ do
    dynflags <- GHC.getSessionDynFlags
    _ <- GHC.setSessionDynFlags dynflags
    m <- GHC.findModule (GHC.mkModuleName moduleName) Nothing

--------------------------------------------------------    
-- The following code works fine in GHC 7.0.4:
--
--  GHC.setContext [] [(m, Nothing)]
--
-- This new code attempts to set context to the module, 
-- but throws an error in GHC 7.2:
--
    (_,oi) <- GHC.getContext
    GHC.setContext [m] oi
--------------------------------------------------------

    fetched <- GHC.compileExpr (moduleName ++ "." ++ externalFuncName)
    return (Unsafe.Coerce.unsafeCoerce fetched :: [LispVal] -> IOThrowsError LispVal)
  defineVar env internalFuncName (IOFunc result)

作為參考,完整代碼可在FFI.hs(github.com)在線獲得。

有沒有人知道如何解決或解決這個問題?

另外,這可能是由於GHC 7.2中新的Safe Haskell更改引起的,還是僅僅是因為修改了GHC API?

當前模塊上下文保留給當前正在編譯的模塊,即當您在上下文中指定模塊時,它們必須明確不是外部的。

相反,您應該在setContext的第二個參數中將所需模塊指定為導入。 這可以這樣做:

GHC.setContext []
  -- import qualified Module
  [ (GHC.simpleImportDecl . GHC.mkModuleName $ moduleName)
    { GHC.ideclQualified = True
    }
  -- -- import qualified Data.Dynamic
  -- , (GHC.simpleImportDecl . GHC.mkModuleName $ "Data.Dynamic")
  --   { GHC.ideclQualified = True
  --   }
  ]
fetched <- GHC.compileExpr $ moduleName ++ "." ++ externalFuncName
return . unsafeCoerce $ fetched
-- or:
-- fetched <- GHC.dynCompileExpr $ moduleName ++ "." ++ externalFuncName
-- return . fromDynamic (error "Illegal type cast") $ fetched

PS :使用GHC.dynCompileExpr可能是個好主意,這樣你就可以避免使用unsafeCoerce 您必須在上下文中為Data.Dynamic添加合格的導入才能使用它,但Data.Dynamic.Dynamic值通常可以更好地使用,因為您可以更優雅地處理類型錯誤。 我在上面的代碼中添加了代碼作為注釋。


更新

這是GHC 7.4.1的語法:

 GHC.setContext -- import qualified Module [ GHC.IIDecl $ (GHC.simpleImportDecl . GHC.mkModuleName $ moduleName) {GHC.ideclQualified = True} ] 

嘗試

GHC.setContext [] [(m,Nothing)]

(來自另一個StackOverflow問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM