delorie.com/djgpp/doc/utils/utils_19.html | search |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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 |