The erl_ddll
module can load and link a linked-in
driver, if run-time loading and linking of shared objects, or
dynamic libraries, is supported by the underlying operating
system.
start() -> {ok, Pid} | {error, Reason}
Types:
Pid = pid()
Reason = term()
Starts ddll_server
. The error return values are
the same as for gen_server:start/3,4
.
start_link() -> {ok, Pid} | {error, Reason}
Types:
Pid = pid()
Reason = term()
Starts ddll_server
and links it to the calling
process. The error return values are the same as for
gen_server:start_link/3,4
.
Stops ddll_server
.
load_driver(Path, Name) -> ok | {error, ErrorDesc}
Types:
Path = Name = string() | atom()
ErrorDesc = term()
Loads and links the dynamic driver Name
. Path
is a file path to the directory containing the driver.
Name
must be a sharable object/dynamic library. Two
drivers with different Path
s cannot be loaded under
the same name. The number of dynamically loadable drivers are
limited by the size of driver_tab
in config.c
.
If the server is not started the caller will crash.
unload_driver(Name) -> ok | {error, ErrorDesc}
Types:
Name = string() | atom()
Reason = term()
Unloads the dynamic driver Name
. This will fail if
any port programs are running the code that is being unloaded.
Linked-in drivers cannot be unloaded. The process must
previously have called load_driver/1
for the driver.
There is no guarantee that the memory where the driver was loaded is freed. This depends on the underlying operating system.
If the server is not started the caller will crash.
loaded_drivers() -> {ok, Drivers}
Types:
Drivers = [Driver()]
Driver = string()
Returns a list of all the available drivers, both (statically) linked-in and dynamically loaded ones.
If the server is not started the caller will crash.
format_error(ErrorDesc) -> string()
Types:
ErrorDesc -- see below
Takes an ErrorDesc
returned by load_driver/2
or unload_driver/1
and returns a string which
describes the error or warning.
Except for the following minor changes, all information in Appendix E of Concurrent Programming in Erlang, second edition, still applies.
Before the driver is unloaded, the finish
function is
called, without arguments, to give the driver writer a chance to
clean up and release memory allocated in driver_init
.
After the driver is loaded, the function
struct driver_entry *driver_init(void *)
is called with
handle
as argument. If the operating system loader cannot
find a function called driver_init
, the driver will not be
loaded. The driver_init
function must initialize a
ErlDrvEntry
struct and return a pointer to it.
The name of the driver, returned from driver_init
must
match the name of the driver, and the file name (with extensions
removed).
Example:
#include <stdio.h> #include "erl_driver.h" static long my_start(ErlDrvPort, char*); static int my_stop(ErlDrvData), my_read(ErlDrvData, char*, int); static ErlDrvEntry my_driver_entry; /* * Initialize and return a driver entry struct */ ErlDrvEntry *driver_init(void *handle) { memset(my_driver_entry, '\0', sizeof(my_driver_entry)); my_driver_entry.start = my_start; my_driver_entry.stop = my_stop; my_driver_entry.output = my_read; my_driver_entry.driver_name = "my_driver"; my_driver_entry.finish = null_func; return &my_driver_entry; }
The size of the driver_tab
array, defined in
config.c
, limits the number of dynamically loadable
drivers.
Please refer to the C compiler or operating system documentation for information about producing a sharable object or DLL.
The include file erl_driver.h
is found in
the usr/include
directory of the Erlang installation. Also
the older file driver.h
is available, but is considered
obsolete.
erl_driver(4), driver_entry(4)