- Erlang - Home
- Erlang - Overview
- Erlang - Environment
- Erlang - Basic Syntax
- Erlang - Shell
- Erlang - Data Types
- Erlang - Variables
- Erlang - Operators
- Erlang - Loops
- Erlang - Decision Making
- Erlang - Functions
- Erlang - Modules
- Erlang - Recursion
- Erlang - Numbers
- Erlang - Strings
- Erlang - Lists
- Erlang - File I/O
- Erlang - Atoms
- Erlang - Maps
- Erlang - Tuples
- Erlang - Records
- Erlang - Exceptions
- Erlang - Macros
- Erlang - Header Files
- Erlang - Preprocessors
- Erlang - Pattern Matching
- Erlang - Guards
- Erlang - BIFS
- Erlang - Binaries
- Erlang - Funs
- Erlang - Processes
- Erlang - Emails
- Erlang - Databases
- Erlang - Ports
- Erlang - Distributed Programming
- Erlang - OTP
- Erlang - Concurrency
- Erlang - Performance
- Erlang - Drivers
- Erlang - Web Programming
Erlang - Drivers
Sometimes we want to run a foreign-language program inside the Erlang Runtime System. In this case, the program is written as a shared library that is dynamically linked into the Erlang runtime system. The linked-in driver appears to the programmer as a port program and obeys exactly the same protocol as for a port program.
Creating a Driver
Creating a linked-in driver is the most efficient way of interfacing foreign-language code with Erlang, but it is also the most dangerous. Any fatal error in the linked-in driver will crash the Erlang System.
Following is an example of a driver implementation in 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.
Please note that working with drivers is extremely complex and care should be taken when working with drivers.
Advertisements