OCaml 在运行时编译和加载

2024-04-05

我正在尝试实现类似的目标eval()在 OCaml 中。

我有一个string我想从中得到一个 OCaml 函数。 目前我正在做以下事情:

我将字符串转储到new.ml并编译文件:

Compile.implementation Format.std_formatter "new.ml" "New"

然后我尝试dynlink文件:

Dynlink.loadfile "new.cmo";

但如果我尝试做New.foo它失败。我不知道为什么我无法访问模块 New 之后Dynlinking。我错过了什么吗?

Thanks!


的评论Dynlink.loadfile says:

没有提供任何设施 访问由单元定义的值名称。因此,单位 必须向主程序注册其入口点, 例如通过修改函数表。

加载程序无法在没有任何提示的情况下访问 dyn 加载模块的值,因为它不知道仅从.cmo文件。动态加载的模块必须将其入口点注册到加载程序中定义的某种状态。

这是一个最小的例子。首先,模块的入口点:

(* entry.ml *)
let f : (unit -> unit) ref = ref (fun () -> assert false)

加载程序:

(* loader.ml *)
let () =
    Dynlink.loadfile "plugin.cmo";
    !Entry.f ()

要动态加载的插件:

(* plugin.ml *)
let () = Entry.f := (fun () -> prerr_endline "hello world")

Here, Plugin将其函数注册到Entry.f它静态链接到Loader, 以便Loader可以访问该功能。

它们必须按如下方式编译:

$ ocamlc -o loader.exe dynlink.cma entry.ml loader.ml
$ ocamlc -c plugin.ml

执行loader.exe应该演示 dyn 加载是如何工作的:

$ ./loader.exe
hello world

注意Entry and Loader必须是不同的模块。否则,你会得到Uninitialized_global动态加载异常Plugin。动态加载的模块只能访问“已初始化模块”中的值,并且加载器模块在以下情况下认为自己尚未初始化:Dynlink.loadfile被调用,因为模块的整个评估尚未完成。

Entry.f是只有一个入口点的最简单状态。要动态加载许多值,您可能需要更复杂的数据结构,例如(string, (unit -> unit)) list ref or (string, (unit -> unit)) Hashtbl.t.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OCaml 在运行时编译和加载 的相关文章

  • 用于查找两个列表之间差异的库函数 - OCaml

    有没有库函数可以找List1 minus elements that appear in List2 我一直在谷歌上搜索并没有发现太多 似乎没有too自己写的很简单 我编写了一个函数来从列表中删除特定元素 但这要简单得多 let rec d
  • OCaml:在 GTK 中嵌入 openGL

    我想将 openGL 图形嵌入 OCaml 中的 GTK 程序中 您对如何做到这一点有什么想法吗 编辑 Tk 似乎已经解决了问题Togl http togl sourceforge net 在我的 ubuntu 中 我有包 liblablg
  • 在 OCaml 中模拟 try-with-finally

    OCaml s try with不提供finally像Java这样的子句 不过 它会很有用 尤其是在处理副作用时 例如 我喜欢打开一个文件 将打开的文件传递给一个函数 然后关闭它 如果函数引发异常 我必须捕获它才能有机会关闭文件 当打开多个
  • 如何将函数应用于变体?

    让这个类型 type intC int type boolC bool type stringC string type component A of intC B of boolC C of stringC 如果我想对组件 A 的类型 a
  • 程序程序员的功能代码片段列表? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 正确编译子文件夹中的模块(ocamlbuild)

    我最近决定整理我的项目目录中的文件 我将几种不同文件类型的解析器移至它们自己的目录中 并决定使用 ocamlbuild 因为项目变得越来越复杂 简单的 shell 脚本不再足够 我能够通过使用一些基本规则修改 myocamlbuild 来成
  • 与 Python 的 range 函数等效的 OCaml 习惯用法是什么?

    我想创建一个从 1 到 的整数列表n 我可以在 Python 中使用range 1 n 1 并在 Haskell 中使用 take n iterate 1 1 正确的 OCaml 习惯用法是什么 我不知道有什么习惯用法 但这里有一个使用中缀
  • 未绑定图形模块

    Running open Graphics OCaml 中返回一个错误 表示它是一个未绑定的模块 在终端 ocaml 中运行它会返回相同的结果 这是否意味着我的图形模块未随 OCaml 软件包一起安装 如果是这样 我该如何安装该模块 在费多
  • 类型注释被推断的表达式类型覆盖

    在 Scala 编程语言中 假设我将使用更广泛的类型注释表达式并提供一个狭窄的值 我的程序将被拒绝 scala gt def x A A 8
  • GADT 上的模式匹配失败

    我更多地使用 ReasonML 并发现了模式匹配type t从以下示例开始 无法处理该错误 错误 此模式与 t float 类型的值匹配 但需要一个与 t int 类型的值匹配的模式 float 类型与 int 类型不兼容 type t a
  • 跟踪编译器中 AST 节点的源位置 (ocaml)

    我正在使用 ocamllex yacc 在 ocaml 中编写编译器 一切进展顺利 但我遇到了设计问题 对于我创建的每个 AST 节点 最好能获得有关源代码中该节点的行 字符位置的信息 这对于稍后向用户提供错误消息很有用 现在 我可以向我的
  • 在 OCaml 中的 let 命令(即 let _ = ... in)中使用下划线通配符有副作用吗?

    使用 OCaml 时 我几乎总是使用下划线通配符let exp 特别是当结果exp并不重要 重要的是里面的计算 例如 let print endline abc in let a a 1 in let do some thing in 所以
  • 在ocaml中编写多行函数

    我无法理解如何在 ocaml 中编写函数 因为我只编写了不需要用 分隔的多行的递归函数 我正在尝试创建一个函数 给定一个整数 n 返回一个充满零且对角线上只有一个的矩阵 因此大小为 n 的单位矩阵 我是函数式编程和 ocaml 的新手 所以
  • 数据中的是什么?

    我使用OCaml版本4 02 3 我定义了一个类型self type self Self of self type self Self of self 及其实例s let rec s Self s val s self Self
  • llvm OCaml 绑定

    我正在研究 llvm OCaml 绑定 我通过 opam 安装了 llvm 包 opam install llvm 当我在 utop 中使用 llvm 时 出现以下错误 require llvm Error The external fun
  • 具有可变参数数量的 OCaml 函数

    我正在探索 OCaml 函数的 高级 用法 我想知道如何编写具有可变数量参数的函数 例如 像这样的函数 let sum x1 x2 x3 xn x1 x2 x3 xn 通过一些类型黑客 当然 let sum f f 0 let arg x
  • 使用 OCaml 警告属性禁用警告 8:不详尽的匹配

    我正在尝试编写类似于以下内容的代码 let a b body 1 2 我想仅针对该模式禁用警告 8 a b 而不是为了身体或让之外的任何东西 我尝试设置警告属性来禁用警告 但以下方法都不起作用 let warning 8 a warning
  • OCaml:如何运行包含库的脚本

    我正在按照 Real World OCaml 一书来学习 OCaml 许多程序都需要使用 Jane Street Core 库 当我在顶层使用这个核心库中的函数时 它工作得很好 在那里 我只需使用以下命令来打开 Core 库 use top
  • 如何使用 opam 安装特定版本的 ocaml 编译器

    如何使用 opam 或其他包管理器 安装特定版本的 ocaml 编译器 和兼容包 我快速浏览了 opam 文档 但没有找到相关信息 我需要 ocaml 编译器 最好是本机代码编译器 来构建 unison 一个文件同步软件 我需要使用相同版本
  • 如何在 OCaml 中使协变可观察

    我正在尝试为值制作一个包装器 允许调用者自行注册以获取有关它的通知 这是一些 工作 代码 module Thing sig type a t val make a gt a t val watch a gt unit gt a t gt u

随机推荐