当我尝试绑定C函数指针时,我正在使用OCaml Ctypes库我有一条错误消息说:Error: Unbound value funptr
我有一个仿函数,用于定义我的lib的绑定:
ecore_evas_functor.ml
open Ctypes
module Bindings (F : Cstubs.FOREIGN) = struct
open F
let eina_bool =
view ~read:((<>) 0) ~write:(fun b -> compare b false) int
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 eina_bool)
let ecore_evas_shutdown =
foreign "ecore_evas_shutdown" (void @-> returning eina_bool)
type ecore_evas = unit ptr
let ecore_evas : ecore_evas typ = ptr void
let ecore_evas_new =
foreign "ecore_evas_new" (string_opt @-> int @-> int @-> int @-> int @-> string_opt @-> returning ecore_evas)
let ecore_evas_title_set =
foreign "ecore_evas_title_set" (ecore_evas @-> string_opt @-> 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)
let ecore_evas_alpha_set =
foreign "ecore_evas_alpha_set" (ecore_evas @-> eina_bool @-> returning void)
end
当我使用这个仿函数时,我能够使用。
生成C存根stubs_generators.ml
(* corebuild -pkg ctypes.foreign,ctypes.stubs -lflags -cclib,-lecore_evas -lflags -cclib,-lecore stubs_generator.native *)
let _ =
let prefix = "ecore_evas_stubs" in
let generate_ml, generate_c = ref false, ref false in
Arg.(parse [ ("-ml", Set generate_ml, "Generate ML");
("-c", Set generate_c, "Generate C") ])
(fun _ -> failwith "unexpected anonymous argument")
"stubgen [-ml|-c]";
match !generate_ml, !generate_c with
| false, false
| true, true ->
failwith "Exactly one of -ml and -c must be specified"
| true, false ->
Cstubs.write_ml Format.std_formatter ~prefix (module Ecore_evas.Bindings)
| false, true ->
print_endline "#include <Ecore.h>\n#include <Ecore_Evas.h>";
Cstubs.write_c Format.std_formatter ~prefix (module Ecore_evas.Bindings)
之后我希望我的模块能够处理测试的回调,所以我在 ecore_evas_functor.ml 中添加它:
let ecore_evas_event_cb = ecore_evas @-> returning void
let ecore_evas_callback_delete_request_set =
foreign "ecore_evas_callback_delete_request_set" (ecore_evas @-> funptr ecore_evas_event_cb @-> returning void)
ecore_evas_functor.ml
open Ctypes
module Bindings (F : Cstubs.FOREIGN) = struct
open F
let eina_bool =
view ~read:((<>) 0) ~write:(fun b -> compare b false) int
let ecore_main_loop_begin =
foreign "ecore_main_loop_begin" (void @-> returning void)
(* same code as before *)
let ecore_evas_alpha_set =
foreign "ecore_evas_alpha_set" (ecore_evas @-> eina_bool @-> returning void)
let ecore_evas_event_cb = ecore_evas @-> returning void
let ecore_evas_callback_delete_request_set =
foreign "ecore_evas_callback_delete_request_set" (ecore_evas @-> funptr ecore_evas_event_cb @-> returning void)
end
我有这个编译错误:
corebuild -pkg ctypes.foreign,ctypes.stubs -lflags -cclib,-lecore_evas -lflags -cclib,-lecore stubs_generator.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,ctypes.stubs -package core -ppx 'ppx-jane -as-ppx' -o ecore_evas.cmo ecore_evas.ml
File "ecore_evas.ml", line 38, characters 69-75:
Error: Unbound value funptr
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 3 targets (1 cached) in 00:00:00.
**编辑**
我最初有一个简单的模块,以便生成正在运行的绑定:
ecore_evas.ml
open Ctypes
open Foreign
let eina_bool =
view ~read:((<>) 0) ~write:(fun b -> compare b false) int
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 eina_bool)
let ecore_evas_shutdown =
foreign "ecore_evas_shutdown" (void @-> returning eina_bool)
type ecore_evas = unit ptr
let ecore_evas : ecore_evas typ = ptr void
let ecore_evas_new =
foreign "ecore_evas_new" (string_opt @-> int @-> int @-> int @-> int @-> string_opt @-> returning ecore_evas)
let ecore_evas_title_set =
foreign "ecore_evas_title_set" (ecore_evas @-> string_opt @-> 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)
let ecore_evas_alpha_set =
foreign "ecore_evas_alpha_set" (ecore_evas @-> eina_bool @-> returning void)
let ecore_evas_event_cb = ecore_evas @-> returning void
let ecore_evas_callback_delete_request_set =
foreign "ecore_evas_callback_delete_request_set" (ecore_evas @-> funptr ecore_evas_event_cb @-> returning void)