dynamically loaded drivers in R7B

Raimo Niskanen <>
Mon Nov 27 12:01:29 CET 2000


I have inserted some answers below.

/ Raimo Niskanen, Erlang/OTP



Vance Shipley wrote:
> 
> I am putting together a dynamically linked and have seen some conflict
> between the documentation and the header file erl_driver.h.
> 
> erl_driver.h:
> 
> typedef struct erl_drv_entry {
>     int (*init)(void);          /* called at system start up for statically
>                                    linked drivers, and after loading for
>                                    dynamically loaded drivers */
> ...
> 
> That makes sense however the erl_ddll documentation says:
> 
> 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.
> 

Well, the text should say that the init function in struct driver_entry
is not _needed_ anymore. It it _is_, however, called, so there are two
functions for the same purpose - confusion. Alas! I am sorry.

For statically linked drivers only the struct driver_entry init function
is called, and for dynamically linked drivers both are called. Since it
is tricky to get a statically linked driver into the runtime system,
this matter may be of small importance.

> Now even to further muddy the waters erl_driver.h has:
> 
> /*
>  * This macro is used to name a dynamic driver's init function in
>  * a way that doesn't lead to conflicts. This is crucial when using
>  * operating systems that has one namespace for all symbols
>  * (e.g. VxWorks). Example: if you have an dynamic driver C source
>  * file named echo_drv.c, you use the macro like this:
>  *
>  *    DRIVER_INIT(echo_drv)
>  *    {
>  *       ....
>  *    }
>  *
>  * This function well be called by the Erlang I/O system when the driver is load
> ed.
>  * It must initialize a ErlDrvEntry structure and return a pointer to it.
>  */
> 
> #if defined(VXWORKS)
> #    define DRIVER_INIT(DRIVER_NAME) ErlDrvEntry* DRIVER_NAME  ## _init(void)
> #elif defined(__WIN32__)
> #    define DRIVER_INIT(DRIVER_NAME) __declspec(dllexport) ErlDrvEntry* driver_i
> nit(void)
> #else
> #    define DRIVER_INIT(DRIVER_NAME) ErlDrvEntry* driver_init(void)
> #endif
> 
> So which is it?  What does myt function get named in my_drv.c and what
> value do I give my_drv_entry.init?
> 
>         -Vance

If I dare guess You do not compile for VxWorks then Your init function
will be named driver_init. In the event I am wrong, it will be named
my_drv_init.

In R7, it is allowed (i reccon) to set my_drv_entry.init to NULL, and it
will not be called be skipped. This was not allowed earlier, since
setting my_drv_entry.init to a function that does nothing is not hard.
The important is that driver_init must return the address to Your
initialized struct my_drv_entry.



More information about the erlang-questions mailing list