Erlang - Trình điều khiển
Đôi khi chúng tôi muốn chạy một chương trình tiếng nước ngoài bên trong Hệ thống thời gian chạy Erlang. Trong trường hợp này, chương trình được viết dưới dạng thư viện chia sẻ được liên kết động vào hệ thống thời gian chạy Erlang. Trình điều khiển được liên kết xuất hiện với lập trình viên dưới dạng chương trình cổng và tuân theo chính xác giao thức giống như đối với chương trình cổng.
Tạo trình điều khiển
Tạo trình điều khiển được liên kết trong là cách hiệu quả nhất để giao tiếp mã ngoại ngữ với Erlang, nhưng nó cũng nguy hiểm nhất. Bất kỳ lỗi nghiêm trọng nào trong trình điều khiển được liên kết sẽ làm hỏng Hệ thống Erlang.
Sau đây là một ví dụ về triển khai trình điều khiển trong Erlang:
Thí dụ
-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.
Xin lưu ý rằng làm việc với trình điều khiển là vô cùng phức tạp và cần cẩn thận khi làm việc với trình điều khiển.