# erl_ddll

### MODULE

erl_ddll

### MODULE SUMMARY

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`. `Name` must be 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, 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 driver 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.

The `driver_entry` struct has two new members: `finish` and `handle`.

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`.

The member `handle` contains a pointer obtained from the operating system when the driver was loaded. Without this, the driver cannot be unloaded!

The `init` function in `struct driver_entry` is not used anymore. 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 `struct driver_entry` and return a pointer to it.

Example:

    #include <stdio.h>
    #include "driver.h"
    static long my_start();
    static int my_stop(), my_read();
    static struct driver_entry my_driver_entry;
    /*
     * Initialize and return a driver entry struct
     */
    struct driver_entry *driver_init(void *handle)
    {
      my_driver_entry.init = null_func;     /* Not used */
      my_driver_entry.start = my_start;
      my_driver_entry.stop = my_stop;
      my_driver_entry.output = my_read;
      my_driver_entry.ready_input = null_func;
      my_driver_entry.ready_output = null_func;
      my_driver_entry.driver_name = "my_driver";
      my_driver_entry.finish = null_func;
      my_driver_entry.handle = handle;  /* MUST set this!!! */
      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 `driver.h` is found in the `usr/include` directory of the Erlang installation.

### AUTHORS

Jan-Erik Dahlin - support@erlang.ericsson.se

kernel 2.7.2
Copyright © 1991-2002 Ericsson Utvecklings AB