使用GHC的API或提示从已编译的二进制文件导入已知函数

我有一个模块
Target
,里面有一个函数
Target.accessMe
。我以某种方式编译这个模块,然后摆脱源代码。 现在,我必须做一系列奥术咒语才能动态导入另一个程序
Target.accessMe
?这个程序提前知道
accessMe
的类型。另外,请考虑
Target
的源代码不可用的事实。
plugins
包设法实现这一目标,但似乎在使用Windows时存在严重问题。我已经查看了
plugins
的来源,但我很难理解它。 我尝试过使用
Hint
,但只能找到如何评估我有源代码的代码。 谢谢你的帮助!     
已邀请:
这个问题的答案已在别处给我。 GHC API能够做到这一点。这里有两个函数,其中一个函数编译
Target.hs
,而另一个函数访问
Target.accessMe
(并且不再需要
Target
模块的源代码)。
import GHC
import DynFlags

compile :: String -> IO SuccessFlag
compile name = defaultRunGhc $ do
  dynflags <- getSessionDynFlags
  let dynflags' = dynflags -- You can change various options here.
  setSessionDynFlags dynflags'

  -- (name) can be "Target.hs", "Target", etc.
  target <- guessTarget name Nothing
  addTarget target
  load LoadAllTargets -- Runs something like "ghc --make".
这是一个编译给定模块的函数,并返回编译是否成功。它使用
defaultRunGhc
辅助函数,定义为:
import GHC.Paths (libdir)

defaultRunGhc :: Ghc a -> IO a
defaultRunGhc = defaultErrorHandler defaultDynFlags . runGhc (Just libdir)
现在是一个从已编译模块中获取值的函数。此时不需要存在模块的源代码。
import Unsafe.Coerce (unsafeCoerce)

fetch :: String -> String -> IO Int -- Assumes we are fetching an Int value.
fetch name value = defaultRunGhc $ do
  -- Again, you can change various options in dynflags here, as above.
  dynflags <- getSessionDynFlags
  let m = mkModule (thisPackage dynflags) (mkModuleName name)
  setContext [] [(m, Nothing)] -- Use setContext [] [m] for GHC<7.

  fetched <- compileExpr (name ++ "." ++ value) -- Fetching "Target.accessMe".
  return (unsafeCoerce fetched :: Int)
就是这样!     
无论如何,
plugins
包都有问题。您可能希望查看Hint。     

要回复问题请先登录注册