English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
A volte vogliamo eseguire un programma di lingua esterna nel sistema di esecuzione Erlang. In questo caso, il programma viene scritto come una libreria condivisa, collegata dinamicamente al sistema di esecuzione Erlang. Nel vedere il programma, il driver collegato è un programma di porta e segue lo stesso protocollo dei programmi di porta.
Creare un driver collegato è il metodo più efficace per interfacciarsi con codice di lingua esterna in Erlang, ma anche il più pericoloso. Qualsiasi errore fatale nel driver collegato può causare il crash del sistema Erlang.
Ecco un esempio di implementazione di un driver in Erlang-
-module(helloworld). -export([start/0, stop/0]). -export([twice/1, sum/2]). start() -> start("example1_drv" ). start(SharedLib) -> case erl_ddll:load_driver("." , SharedLib) of ok -> ok; {error, already_loaded} -> ok; _ -> exit({error, could_not_load_driver}) end, spawn(fun() -> init(SharedLib) end). init(SharedLib) -> register(example1_lid, self()), Port = open_port({spawn, SharedLib}, []), loop(Port). stop() -> example1_lid ! stop. twice(X) -> call_port({twice, X}). sum(X,Y) -> call_port({sum, X, Y}). call_port(Msg) -> example1_lid ! {call, self(), Msg}, receive {example1_lid, Result} -> Result end. LINKED-IN DRIVERS 223 loop(Port) -> receive {call, Caller, Msg} -> Port ! {self(), {command, encode(Msg)}}, receive {Port, {data, Data}} -> Caller ! {example1_lid, decode(Data)} end, loop(Port); stop -> Port ! {self(), close}, receive {Port, closed} -> exit(normal) end; {'EXIT', Port, Reason} -> io:format("~p ~n", [Reason]), exit(port_terminated) end. encode({twice, X}) -> [1, X]; encode({sum, X, Y}) -> [2, X, Y]. decode([Int]) -> Int.
请注意,使用驱动程序极为复杂,在使用驱动程序时应格外小心。