Модуль загрузки с dynlink повторно инициализирует значения верхнего уровня - PullRequest
4 голосов
/ 17 января 2011

У меня есть проблема, когда у меня есть глобальная хеш-таблица, а затем я загружаю файл .cma с помощью Dynlink, которая регистрирует функцию в хеш-таблице.

Однако я, похоже, вижу поведение, когда модуль динамически связан, все глобальные привязки переинициализируются, так что моя хеш-таблица пуста.

например:.

Table.extensions : (string, string -> string) Hashtbl.t
Extensions.load : unit -> unit (* loads the specified .cma files *)
Extensions.register : string -> (string -> string) -> unit
  (* adds entry to Table.extensions, prints name of extension registered *)
Main:
let () =
  Extensions.load ();
  Hashtbl.iter (fun x _ -> print_endline x) Table.extensions;
  Printf.printf "%d extensions loaded\n" (Hashtbl.length Table.extensions)

Моя программа загружает один файл .cma, поэтому должен напечатать:

Registered extension 'test'
test
1 extensions loaded

Вместо этого я получаю:

Registered extension 'test'
0 extensions loaded

Я боролся с этим уже несколько часов; независимо от того, как я выполняю рефакторинг своего кода, я не подхожу к работающему решению.

РЕДАКТИРОВАТЬ: Extensions.load:

Dynlink.allow_unsafe_modules true;;

let load () =
  try
    let exts = Sys.readdir "exts" in
    Array.iter begin fun name ->
      try
        Dynlink.loadfile (Filename.concat "exts" name);
        Printf.printf "Loaded %s\n" name;
      with
        | Dynlink.Error error -> print_endline (Dynlink.error_message error)
        | exn -> print_endline (Printexc.to_string exn)
      end exts
  with _ -> ()

1 Ответ

2 голосов
/ 17 января 2011

@ ygrek, вы были правы, было два случая.

Решение было собрать / загрузить только .cmo, а не .cma.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...