У меня проблема, когда у меня есть глобальная хеш-таблица, а затем я загружаю .cma-файл с помощью Dynlink, который регистрирует функцию в хеш-таблице.Загрузочный модуль с 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
Я был борясь с этим в течение нескольких часов; независимо от того, как я реорганизую свой код, я не приближаюсь к рабочему решению.
EDIT: 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 _ ->()
Вы уверены, что расширение регистрируется в том же хэштбле, которое используется основной программой? То есть Разве не возможно, что есть два экземпляра «Таблица.экстензий»? – ygrek
Можете ли вы опубликовать немного больше кода? В частности, было бы полезно увидеть, что делает 'Extensions.load'. –
Два экземпляра Table.extensions? Если это так, как я могу это предотвратить? – jessicah