Erlang-drivers

提供:Dev Guides
移動先:案内検索

Erlang-ドライバー

Erlangランタイムシステム内で外国語プログラムを実行したい場合があります。 この場合、プログラムは共有ライブラリとして記述され、Erlangランタイムシステムに動的にリンクされます。 リンクインドライバーは、プログラマーにはポートプログラムとして認識され、ポートプログラムとまったく同じプロトコルに従います。

ドライバーを作成する

リンクインドライバーを作成することは、外国語コードをErlangとインターフェイスさせる最も効率的な方法ですが、最も危険でもあります。 リンクインドライバーで致命的なエラーが発生すると、Erlangシステムがクラッシュします。

以下は、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.

ドライバーでの作業は非常に複雑であり、ドライバーでの作業には注意が必要です。