Ctypes:带有funptr

时间:2016-09-04 19:18:53

标签: ocaml

当我尝试绑定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)

1 个答案:

答案 0 :(得分:0)