erl_ddll(3)

MODULE
erl_ddll - Dynamic Driver Loader and Linker

DESCRIPTION

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.

EXPORTS

start() -> {ok, Pid} | {error, Reason}

    Starts ddll_server. The error return values are the same as for gen_server.

start_link() -> {ok, Pid} | {error, Reason}

    Starts ddll_server and links it to the calling process. The error return values are the same as for gen_server.

stop() -> ok

    Stops ddll_server.

load_driver(Path, Name) -> ok | {error, ErrorDescriptor}

    Types
        Name = string() | atom()
        Path = string() | atom()

    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 Paths 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, ErrorDescriptor}

    Types
        Name = string() | atom()

    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, DriverList}

    Types
        DriverList = [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(ErrorDescriptor) -> string()

    Takes an ErrorDescriptor which has been returned by one of load_driver/2 and unload_driver/1 and returns a string which describes the error or warning.

Differences Between Statically Linked-in Drivers and Dynamically Loaded Drivers

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;
}

config.c

The size of the driver_tab array, defined in config.c, limits the number of dynamically loadable drivers.

Compiling Your Driver

Please refer to your 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.

SEE ALSO

erl_driver(4), driver_entry(4)

AUTHORS
Jan-Erik Dahlin - support@erlang.ericsson.se
Jakob Cederlund - support@erlang.ericsson.se