This
utility allows you to load an object file from disk and link it to a running
executable. This facility consists of the following parts:
·
The dynloader.dll file, which should be in your PATH variable
·
The bind utility
The
dynloader.dll exports three functions that are of interest here:
1.
LoadObjectFile
2.
GetProcedureAddress
3.
UnloadObjectFile
The
interface is very similar to that of LoadLibrary, since the functionality is
quite similar.
The
dynamic loader operates by opening the given object, allocating space in RAM for
the data and the code stored in there, copying the contents of the data and code
sections, then fixing up everything.
To
resolve external references, the loader relies first on the symbol table of the
running executable. If that symbol table exists, it will be used to resolve
external references from the object file.
If
the symbol table is absent in the running executable, or a symbol is found that
does not match any executable symbols, the dynamic loader will rely on the
imports table generated by the bind utility. This table contains the DLLs used
by the object file, and all the imported functions that are needed.
The
bind utility will construct this table from the “apilist.txt” file, which is
present in the lcc-win32 distribution in the “lib” directory. This file
contains a list of all known DLLs and their exported functions. Using this list,
the bind utility appends a list of needed DLLs to the object file, that will be
used by the dynloader.dll library.
Note
that if you wish to add a DLL of your own to the list, you can do so by
modifying apilist.txt.
Before
loading an object file it must be "bound" using the "bind.exe"
utility. The syntax of the "bind" command is very simple:
bind <object file>
This
will build a list of the DLLs needed by the object file so that it can be
quickly loaded later.
An
object file is loaded using the LoadObjectFile function. The result can be
either NULL, meaning the object file could not be found, or a pointer to an
OBJECT_FILE structure, containing information about the loaded object. Please
note that the members of the structure will probably change in future releases,
so it is not a very good idea to use them in your code. You can still look at
them and they are provided for debugging purposes.
This
is accomplished with the GetProcedureAddress function. The pointer returned
(that can be NULL if the name is not found) should be cast to match the function
prototype. Note that the name of the procedure to be found should match the name
as exported from the object file, i.e., you should add the leading underscore
and the _stdcall decoration if any. For instance for the function
void
hello(void)
you
should pass _hello to the loader. For a _stdcall function, you should add
‘@’ and the size of the function stack.
This
is accomplished using the UnloadObjectFile function. All memory used by the
object file and its descriptors is reclaimed. You should ensure that no further
uses of the object file occur.
#include
<dynloader.h>
int
main(void)
{
OBJECT_FILE *obj =
LoadObjectFile("hello.obj");
void (*fn)(void);
fn =
GetProcedureAddress(obj,"_hello");
(*fn)();
UnloadObjectFile(obj);
return 0;
}