简体   繁体   English

ghc 7.4.2,动态调用模块

[英]ghc 7.4.2, Dynamically calling modules

I am trying to load and execute module dynamically, 我正在尝试动态加载和执行模块,

Below is my code 以下是我的代码

TestModule.hs TestModule.hs

module TestModule
        where

evaluate = "Hello !!!"

Invoke.hs Invoke.hs

module Invoke
        where

import GHC
import DynFlags
import GHC.Paths (libdir)
import Unsafe.Coerce (unsafeCoerce)
import Data.Dynamic

execFnGhc :: String -> String -> Ghc a
execFnGhc modname fn = do
        mod <- findModule (mkModuleName modname) Nothing
        --setContext [IIModule mod]
        GHC.setContext [ GHC.IIDecl $ (GHC.simpleImportDecl . GHC.mkModuleName $ modname) {GHC.ideclQualified = True} ]
        value <- compileExpr (modname ++ "." ++ fn)
        let value' = (unsafeCoerce value) :: a
        return value'

Main2.hs Main2.hs

import GHC.Paths (libdir)
import GHC
import Invoke
--    import TestModule

main :: IO ()
main = runGhc (Just libdir) $ do
                        str <- execFnGhc "TestModule" "evaluate"
                        return str

When I try to run the program it show me below error 当我尝试运行该程序时,它会向我显示以下错误

[root@vps mypproj]# ./Main2 
Main2: <command line>: module is not loaded: `TestModule' (./TestModule.hs)

Not sure what I am missing, Can someone please help me resolve this error 不确定我错过了什么,有人可以帮我解决这个错误

My thought would be the problem has something to do with your path,and that the program silently errors when it can't load "TestModule," then complains that the module is not loaded. 我的想法是问题与你的路径有关,并且程序在无法加载“TestModule”时会默默地出错,然后抱怨模块没有被加载。 Have you tried using execFnGhc with a module that is already loaded, and have you tried loading a module that is in GHC naturally, such as Text.Parsec, then executing something in it? 您是否尝试将execFnGhc与已加载的模块一起使用,并且您是否尝试过自然地加载GHC中的模块,例如Text.Parsec,然后在其中执行某些操作?

I'd test myself, but I don't see a GHC.Paths library anywhere :/. 我会测试自己,但我没有在任何地方看到GHC.Paths库:/。

I was reading the relevant GHC source code recently, and it looks like findModule doesn't work on local modules ( TestModule.hs in your case) unless they've already been loaded. 我最近正在阅读相关的GHC源代码,看起来findModule对本地模块(在你的情况下为TestModule.hs )不起作用,除非它们已经被加载。 (It works on modules in remote packages, however.) (但它适用于远程包中的模块。)

To do GHCi style dynamic loading of compiled modules, your best bet is to use addTarget and load . 要做GHCi样式动态加载已编译的模块,最好的办法是使用addTargetload As was mentioned in the comments, you also need to initialize the session dynamic flags. 正如评论中提到的,您还需要初始化会话动态标志。 Here is a working version of your code: 这是您的代码的工作版本:

module Invoke
        where

import GHC
import DynFlags
import GHC.Paths (libdir)
import Unsafe.Coerce (unsafeCoerce)
import Data.Dynamic

execFnGhc :: String -> String -> Ghc String
execFnGhc modname fn = do
        dflags <- getDynFlags
        setSessionDynFlags dflags
        let target = Target (TargetModule (mkModuleName modname)) True Nothing
        addTarget target
        load (LoadUpTo (mkModuleName modname))
        mod <- findModule (mkModuleName modname) Nothing
        GHC.setContext [ GHC.IIDecl $ (GHC.simpleImportDecl . GHC.mkModuleName $ modname) {GHC.ideclQualified = True} ]
        value <- compileExpr (modname ++ "." ++ fn)
        let value' = (unsafeCoerce value) :: String
        return value'

What are the parameters of Target ? Target的参数是什么? The first is the module name; 第一个是模块名称; the second is whether or not we should be allowed to load object code, or always interpret the module; 第二个是我们是否应该被允许加载目标代码,或者总是解释模块; the last is an optional string buffer which you could use to override the source code in the actual file (it's Nothing because we don't need this.) 最后一个是可选的字符串缓冲区,您可以使用它来覆盖实际文件中的源代码(它Nothing因为我们不需要它。)

How did I figure this out? 我怎么知道这个? I looked at the code that GHCi uses to implement this in the GHC source code, as well as the compiler/main/GHC.hs . 我查看了GHCi用于在GHC源代码中实现它的代码,以及compiler/main/GHC.hs I've found this is the most reliable way to figure out how to get the GHC API to do what you want. 我发现这是了解如何让GHC API做你想做的最可靠的方法。

Confusing? 混乱? The GHC API was not so much designed as accreted... GHC API的设计并不像增加的......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM