OCaml build error : type int instead of type unit
OCaml build error : type int instead of type unit
我想试用 OCaml FFI 并绑定一些 C 函数,例如
ncurses 教程,但我选择了 ecore_evas (efl):
以下是我想使用的功能:
void ecore_main_loop_quit(void)
void ecore_main_loop_begin(void)
int ecore_evas_init(void)
int ecore_evas_shutdown(void)
Ecore_Evas * ecore_evas_new(const char *, int, int, int, int, const char *)
ecore_evas_title_set(const Ecore_Evas *, const char *)
ecore_evas_show(ee)
ecore_evas_free(ee)
所以我用这个创建文件 ecore_evas.ml:
open Ctypes
open Foreign
let ecore_main_loop_begin = foreign "ecore_main_loop_begin" (void @->
returning void)
let ecore_main_loop_quit = foreign "ecore_main_loop_quit" (void @->
returning void)
let ecore_evas_init = foreign "ecore_evas_init" (void @-> returning int)
let ecore_evas_shutdown = foreign "ecore_evas_shutdown" (void @->
returning int)
type ecore_evas = unit ptr
let ecore_evas : ecore_evas typ = ptr void
let ecore_evas_new = foreign "ecore_evas_new" (string @-> int @-> int
@-> int @-> int @-> string @-> returning ecore_evas)
let ecore_evas_title_set = foreign "ecore_evas_title_set" (ecore_evas
@-> string @-> returning void)
let ecore_evas_show = foreign "ecore_evas_show" (ecore_evas @->
returning void)
let ecore_evas_free = foreign "ecore_evas_free" (ecore_evas @->
returning void)
然后我用这些命令创建了一个 mli 文件:
corebuild -pkg ctypes.foreign ecore_evas.inferred.mli
cp _build/ecore_evas.inferred.mli ./
ecore_evas.inferred.mli
val ecore_main_loop_begin : unit -> unit
val ecore_main_loop_quit : unit -> unit
val ecore_evas_init : unit -> int
val ecore_evas_shutdown : unit -> int
type ecore_evas = unit Ctypes.ptr
val ecore_evas : ecore_evas Ctypes_static.typ
val ecore_evas_new : bytes -> int -> int -> int -> int -> bytes ->
ecore_evas
val ecore_evas_title_set : ecore_evas -> bytes -> unit
val ecore_evas_show : ecore_evas -> unit
val ecore_evas_free : ecore_evas -> unit
然后我创建了一个 ecore_evas_window.ml:
open Ecore_evas
let () =
ecore_main_loop_begin ();
ecore_evas_init ();
let ee = ecore_evas_new "" 50 50 300 300 "" in
ecore_evas_title_set ee "This is a test";
ecore_evas_show ee
然后我尝试用
编译
corebuild -pkg ctypes.foreign -lflags -cclib,-lecore_evas
ecore_evas_window.native
但是我有这个错误信息:
+ ocamlfind ocamlc -c -w A-4-33-40-41-42-43-34-44 -strict-sequence -g
-bin-annot -short-paths -thread -package ctypes.foreign -package core
-ppx 'ppx-jane -as-ppx' -o ecore_evas_window.cmo ecore_evas_window.ml
File "ecore_evas_window.ml", line 4, characters 2-21:
Error: This expression has type int but an expression was expected of type
unit
Command exited with code 2.
Hint: Recursive traversal of subdirectories was not enabled for this build,
as the working directory does not look like an ocamlbuild project (no
'_tags' or 'myocamlbuild.ml' file). If you have modules in
subdirectories,
you should add the option "-r" or create an empty '_tags' file.
To enable recursive traversal for some subdirectories only, you can
use the
following '_tags' file:
true: -traverse
<dir1> or <dir2>: traverse
Compilation unsuccessful after building 4 targets (3 cached) in 00:00:00.
此消息清楚地表明问题与线路有关
ecore_evas_init ();
但我真的不明白为什么它会产生这个错误。
编辑
由于@hcarty,原始问题已得到解决,但完整代码无法正常工作。如果需要,可以找到工作版本 here
ecore_evas_init
return 一个 int
。该行的 ;
隐含地表示 "the expression to the left returns unit
"。由于 ecore_evas_init ()
returns 是一个整数,所以类型不匹配。您有几个简单的选项可用:
将现有行替换为:
let _ = ecore_evas_init () in
这将忽略 returned 值。
对 return 值执行一些检查:
assert (ecore_evas_init () = 0); (* Or whatever the "success" status is *)
明确忽略结果:
ignore(ecore_evas_init ());
大致相当于let _ = ...
在完整的应用程序中,您可能需要更复杂的错误处理,但这应该足以继续此示例应用程序。
我想试用 OCaml FFI 并绑定一些 C 函数,例如 ncurses 教程,但我选择了 ecore_evas (efl):
以下是我想使用的功能:
void ecore_main_loop_quit(void)
void ecore_main_loop_begin(void)
int ecore_evas_init(void)
int ecore_evas_shutdown(void)
Ecore_Evas * ecore_evas_new(const char *, int, int, int, int, const char *)
ecore_evas_title_set(const Ecore_Evas *, const char *)
ecore_evas_show(ee)
ecore_evas_free(ee)
所以我用这个创建文件 ecore_evas.ml:
open Ctypes
open Foreign
let ecore_main_loop_begin = foreign "ecore_main_loop_begin" (void @->
returning void)
let ecore_main_loop_quit = foreign "ecore_main_loop_quit" (void @->
returning void)
let ecore_evas_init = foreign "ecore_evas_init" (void @-> returning int)
let ecore_evas_shutdown = foreign "ecore_evas_shutdown" (void @->
returning int)
type ecore_evas = unit ptr
let ecore_evas : ecore_evas typ = ptr void
let ecore_evas_new = foreign "ecore_evas_new" (string @-> int @-> int
@-> int @-> int @-> string @-> returning ecore_evas)
let ecore_evas_title_set = foreign "ecore_evas_title_set" (ecore_evas
@-> string @-> returning void)
let ecore_evas_show = foreign "ecore_evas_show" (ecore_evas @->
returning void)
let ecore_evas_free = foreign "ecore_evas_free" (ecore_evas @->
returning void)
然后我用这些命令创建了一个 mli 文件:
corebuild -pkg ctypes.foreign ecore_evas.inferred.mli
cp _build/ecore_evas.inferred.mli ./
ecore_evas.inferred.mli
val ecore_main_loop_begin : unit -> unit
val ecore_main_loop_quit : unit -> unit
val ecore_evas_init : unit -> int
val ecore_evas_shutdown : unit -> int
type ecore_evas = unit Ctypes.ptr
val ecore_evas : ecore_evas Ctypes_static.typ
val ecore_evas_new : bytes -> int -> int -> int -> int -> bytes ->
ecore_evas
val ecore_evas_title_set : ecore_evas -> bytes -> unit
val ecore_evas_show : ecore_evas -> unit
val ecore_evas_free : ecore_evas -> unit
然后我创建了一个 ecore_evas_window.ml:
open Ecore_evas
let () =
ecore_main_loop_begin ();
ecore_evas_init ();
let ee = ecore_evas_new "" 50 50 300 300 "" in
ecore_evas_title_set ee "This is a test";
ecore_evas_show ee
然后我尝试用
编译corebuild -pkg ctypes.foreign -lflags -cclib,-lecore_evas
ecore_evas_window.native
但是我有这个错误信息:
+ ocamlfind ocamlc -c -w A-4-33-40-41-42-43-34-44 -strict-sequence -g
-bin-annot -short-paths -thread -package ctypes.foreign -package core
-ppx 'ppx-jane -as-ppx' -o ecore_evas_window.cmo ecore_evas_window.ml
File "ecore_evas_window.ml", line 4, characters 2-21:
Error: This expression has type int but an expression was expected of type
unit
Command exited with code 2.
Hint: Recursive traversal of subdirectories was not enabled for this build,
as the working directory does not look like an ocamlbuild project (no
'_tags' or 'myocamlbuild.ml' file). If you have modules in
subdirectories,
you should add the option "-r" or create an empty '_tags' file.
To enable recursive traversal for some subdirectories only, you can
use the
following '_tags' file:
true: -traverse
<dir1> or <dir2>: traverse
Compilation unsuccessful after building 4 targets (3 cached) in 00:00:00.
此消息清楚地表明问题与线路有关
ecore_evas_init ();
但我真的不明白为什么它会产生这个错误。
编辑 由于@hcarty,原始问题已得到解决,但完整代码无法正常工作。如果需要,可以找到工作版本 here
ecore_evas_init
return 一个 int
。该行的 ;
隐含地表示 "the expression to the left returns unit
"。由于 ecore_evas_init ()
returns 是一个整数,所以类型不匹配。您有几个简单的选项可用:
将现有行替换为:
let _ = ecore_evas_init () in
这将忽略 returned 值。
对 return 值执行一些检查:
assert (ecore_evas_init () = 0); (* Or whatever the "success" status is *)
明确忽略结果:
ignore(ecore_evas_init ());
大致相当于
let _ = ...
在完整的应用程序中,您可能需要更复杂的错误处理,但这应该足以继续此示例应用程序。