Erlang - Conductores
A veces queremos ejecutar un programa en un idioma extranjero dentro del Erlang Runtime System. En este caso, el programa se escribe como una biblioteca compartida que está vinculada dinámicamente al sistema de ejecución de Erlang. El controlador vinculado le aparece al programador como un programa de puerto y obedece exactamente el mismo protocolo que para un programa de puerto.
Crear un controlador
La creación de un controlador vinculado es la forma más eficaz de interconectar código de idioma extranjero con Erlang, pero también es la más peligrosa. Cualquier error fatal en el controlador vinculado bloqueará el sistema Erlang.
A continuación se muestra un ejemplo de una implementación de controlador en Erlang:
Ejemplo
-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.
Tenga en cuenta que trabajar con conductores es extremadamente complejo y se debe tener cuidado al trabajar con conductores.