delorie.com/djgpp/doc/utils/utils_19.html   search  
DJGPP Utilities Reference

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

19. dxe3gen

Usage: dxe3gen [-o output.dxe] [options] [object-files] [ld-options]

 
-o output.dxe	Define the name of output DXE file
-P module.dxe	Specify dependency module (cumulative)
-I import.a	Create an import library for given DXE file
-Y import.a	Create autoresolved import library for given DXE file
-D description	Set module description string
-E prefix	Export only symbols that start with <prefix> (cumulative)
-X prefix	Exclude symbols that start with <prefix> (cumulative)
-U		Allow unresolved symbols in DXE file
-V		Verbose output (minimal output by default)
--show-dep	Show dependencies for specified module
--show-exp	Show symbols exported by the DXE module
--show-unres	Show unresolved symbols in the DXE module
[ld-options]	Any other options are passed unchanged to ld

dxe3gen is a utility which allows you to create files which contain dynamically loadable code (DXE). DXE is used as a synonym for `dynamically loadable executable module', also called sometimes `dynamic modules' or simply `modules' in this document. File names provided as arguments should not contain special characters that require quoting or they may not be passed properly to ld.

There are several ways to use DXE modules. You may either load/unload modules at runtime or to link with them (or rather with so-called `import libraries') at link time (e.g. statically link with dynamic libraries).

dxe3gen allows you to build either dynamic modules that don't have unresolved symbols as well as dynamic modules that DO have unresolved symbols (and allows you to resolve them at runtime). If your DXE references symbols in your main image, you must provide it the locations for those symbols or use the dxe3res command.

Statically linking against dynamic libraries allows for a easy way to introduce dynamic modules into any program. `Static linking' means that during linking stage of your program you link against certain library, called a `import library' in the following, which provides all the functions present in certain DXE module. The symbols points to some very small wrappers, and when you call any of those functions, the library is automatically loaded and the call is redirected further. Also you may load/unload the library manually by calling some special functions called dlload_MODNAME and dlunload_MODNAME functions (where MODNAME stands for the name of your dynamic module).

The dxe3gen tool can build these import libraries, so basically you just take a existing DXE module and generate the corresponding import library for this module (see the `Import libraries' section). Then you link against it... and voila! it works.

Static linkage against dynamic libraries has a drawback: you CANNOT have exported data inside the library (at least you can't use it). This happens because the symbols are resolved to the wrappers and not to the actual symbols inside the module. That is, if you have a variable called i in a dynamic module, and you assign i = 1 from your program which is statically linked against that module, you will actually write over the wrapper and not into the actual location where the contents of i are. If you really need to set/get values of some variables inside a dynamic module, write a couple of set_i and get_i *functions*.

Some modules require other modules to be already loaded when they are hit (either via dlopen() or a call into their corresponding import library). Don't worry about that: just use the -P (dependency) option of the generator.

Another way to use DXE modules is implemented through the dlopen() API (@xref{dlopen, , dlopen, libc}). This API closely mimics the one found on many Unix-like systems, thus you may even build some Unix applications that use dynamic libraries without a single change.

The dynamic loader supports initialization and finalization functions inside dynamic libraries. You may use the standard C/C++ way of doing initialization/finalization, for example (C++):

 
	class __init
	{
	  __init ()
	  {
	    ... initialization stuff
	  }
	  ~__init ()
	  {
	    ... finalization stuff
	  }
	} __dummy_object;

The above approach will work on any platform with a C++ compiler. During program (or shared library) startup the constructor for the __dummy_object is called, and during program (or shared library) shutdown the destructor is invoked. For plain C you will have to use the GNU C extensions:

 
	void __attribute__((constructor)) __init_func ()
	{
	  ... initialization stuff
	}

	void __attribute__((destructor)) __finit_func ()
	{
	  ... finalization stuff
	}


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster     delorie software   privacy  
  Copyright © 2004     Updated Nov 2004