司机( Drivers)
优质
小牛编辑
125浏览
2023-12-01
有时我们想在Erlang Runtime System中运行一个外语程序。 在这种情况下,程序被编写为动态链接到Erlang运行时系统的共享库。 链接的驱动程序对程序员来说是一个端口程序,并且遵循与端口程序完全相同的协议。
创建驱动程序
创建链接驱动程序是将外语代码与Erlang连接的最有效方法,但它也是最危险的。 链接驱动程序中的任何致命错误都会使Erlang系统崩溃。
以下是Erlang中驱动程序实现的示例 -
例子 (Example)
-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.
请注意,与司机合作非常复杂,在与司机合作时应该小心。