我有一个模块Target
,有一个函数Target.accessMe
在里面。我以某种方式编译这个模块,然后删除源代码。
现在,我必须执行哪些神秘咒语才能动态导入不同的程序Target.accessMe
?这个程序知道accessMe
提前输入。另外,请考虑以下事实:Target
不可用。
The 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)
就是这样!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)