[lcdproc] Dynamic linking FUD :) (long)

Ed Hunter ed.hunter@seznam.cz
Fri, 21 Sep 2001 23:44:08 +0200


Hi, folks,


with this long and hairy mail I would like to clear some FUD which 
happily proliferates on this maillist. I will try to show you that it's 
possible to use dynamic linking easily, that it allows for multiple 
drivers, does NOT require anything to be hardcoded and that it's The 
Right Way To Go (tm)


- first of all, dynamic linking on Linux works well. I have already 
tried loading drivers with it (not for lcd) and it works like a charm.

- apache historically used static linking but it usually uses dynamic 
linking now. Modules define table with function pointers just as I 
showed you

- netscape httpd used similar approach, with entry points and .so files 
named in config file

- there's no problem having driver specific prefix for entry points, 
since you can name that prefix in config file too. On the other hand, 
single entry point name for all drivers will prevent static linking (and 
does not work on Windoze, AFAIK)

That said, the drivers could be used like this with lcd:

File lcd.conf:

[main]
driver_dir=/usr/lib/lcd
driver_list=mtxorb,hd4478,lirc

[driver_mtxorb]
lib=mtxorb.so

[driver_hd4478]
lib=hd4478drv.so
options=use_quick_parport

[driver_lirc]
lib=lirc.so

[display_main]
driver=hd4478
device=/dev/whatever0
size=16x2

[display_bigone]
driver=mtxorb
device=/dev/whatever34
size=20x4
options=backlight,......

[display_small]
driver=hd4478
device=/dev/whatever45
size=16x1

[app_lcdecho]
display=display_main

Ok. Now for example hd4478drv.c:

#include <lcd_plugin_api.h>
#include <lcd_display.h>

Lcd_Plugin_API  hd4478_api = {
     TYPE_OUTPUT,
     hd4478_open,
     hd4478_close,
     hd4478_flush,
};

int hd4478_open (Display *display) {
   /* opens device display->device, fills in display */
}

int hd4478_close (Display *display) {
}

int hd4478_flush (Display *display) {
   /* takes framebuffer from the display and flushes it to the hd4478 
LCD display */
}

static char some_fn () {
}

And now for example lcd_echo.c, simple proggie to display string on any 
one display attached to the system:

Usage:lcd_echo -d <display_name> <string_to_display>

....

int main (int argc, char **argv) {

   /* reads display_name and string_to_display */
   parse_params (argc, argv);
   ini_open (config_file);

   driver_name = ini_get_key_in_section ("display_"+display_name, 
"driver", NULL);
   lib_name = ini_get_key_in_section ("driver_"+driver_name, "lib", NULL);
   lib_api_name = driver_name + "_api";

   hnd = dlopen (lib_name, RTLD_LOCAL);
   api = dlsym (hnd, lib_api_name);

   /* malloces Display struct and fills it's fields like device, size 
etc. */
   display = new_display (display_name);
   api->open (display);
   display_write (display, string_to_display);
   api->flush (display);
   api->close (display);
   ini_close ();
}


(Note: I use string+string in this pseudocode to avoid mallocs and 
strcats. Also no checking is done)

Why to use api tables at all? One reason is that data objects are not 
subject to name mangling when linking with C++


What do you think?

				Jarda Benkovsky



-----------------------------------------------------------
To unsubscribe from this list send a blank message to
lcdproc-unsubscribe@lists.omnipotent.net