[英]OCaml type constructors in C = <unknown constructor>
我为一些 C 代码编写了一些 OCaml 绑定; 它们似乎工作正常,只是在解释器中,类型构造函数似乎对 OCaml 不透明。 因此,例如:
# #load "foo.cma" ;;
# open Foo ;;
# let b = barbie "bar";;
val b : Foo.kung = <unknown constructor>
# let k = ken "kenny" ;;
val k : Foo.tza = <abstr>
我试图摆脱<unknown constructor>
并用有意义的打印替换它。
foo.ml
的内容是:
type kung = Tsau of string [@@boxed] ;;
type tza ;; (* Obviously, an abstract type *)
external barbie : string -> kung = "barbie_doll" ;;
external ken : string -> tza = "ken_doll" ;;
C 代码是使其工作的最少代码:
CAMLprim value barbie(value vstr) { ... }
CAMLprim value ken(value vsttr) { ... }
实际的 C 代码使用caml_alloc_custom()
来保存东西; 并且显然必须返回caml_alloc_custom()
分配的内容,以免丢失。 这是使用自定义类型的核心原因:所以我可以返回自定义 malloc 的。
即使这些类型是抽象的或不透明的,我还是想让let
表达式打印一些有意义的东西。 例如,也许这个?
val b : Foo.kung = "Hi my name is bar"
val k : Foo.tza = "Yo duude it's kenny"
第二个问题是:如果可以打印一些有意义的东西,它应该是什么? 显然,构造函数是用字符串调用的,所以打印的任何内容都应该包括这些字符串值......
第三个问题是:在C中是否可以指定类型和类型构造函数? 我怀疑答案是否定的,因为 OCaml 类型是静态的、编译时类型,并且不可动态构造。 但问起来从来没有坏处。 我的意思是, ocaml
解释器能够很好地处理全新的类型声明,所以不知何故,OCaml 类型并不是完全静态的; 他们有某种“动态”的一面。 我没有找到任何关于此的文档。
正如评论中所建议的,答案是使用#install_printer
,它在顶级文档 中简要介绍过。 这只是一个提示:示例代码如下(与前面的示例保持一致)。
在foostubs.ml
:
(** Signature declarations for C functions *)
external kung_prt : kung -> string = "c_kung_str" ;;
(* Need to #install_printer kung_pretty ;;
* FYI, the OCaml documentation is confusing
* as to what a Format.formatter actually is:
* it is used like a C stream or outport. *)
let kung_pretty : Format.formatter -> kung -> unit =
function oport ->
fun x -> Format.fprintf oport "Hi %s" (kung_prt x) ;;
C 语言中的打印机如下所示:
CAMLprim value c_kung_str(value vkung)
{
CAMLparam1(vkung);
const char* name = String_val(vkung);
char buff[200];
strcpy(buff, "my name is ");
strncat(buff, name, 200);
CAMLreturn(caml_copy_string(buff));
}
然后,要么你必须告诉用户#install_printer kung_pretty ;;
或者,更好的是,为用户提供执行此操作的setupfoo.ml
,并告诉他们#use "setupfoo.ml"
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.