[Main]
Name=LoadDLL
Type=Function
Subtype=tigcc.a
Header Files=dll.h
Definition=short LoadDLL (const char *VarName, unsigned long ID, unsigned short Major, unsigned short Minor);
See Also=UnloadDLL, LoadDLLThrow, _DLL_call, _DLL_call_attr, _DLL_reference, _DLL_glbvar

[Description]
Loads a DLL into memory and prepares it for use.

[Explanation]
LoadDLL tries to load a DLL into memory and to prepare it for use. It traverses the
complete VAT to find a fitting version of the DLL (so it is not necessary for the DLL to be in
the same directory as the main program). The <I>DLLName</I> parameter is the standard ANSI C name of
the DLL file which is to be loaded. The <I>ID</I> parameter is a DLL identification number introduced for safety
reasons: any file which does not have the extension 'DLL', a valid embedded signature and
an embedded identification number which is equal to <I>ID</I> is ignored (the identification
number in the DLL itself is set using the <A HREF="$$LINK(DLL_ID)">DLL_ID</A> entry in the DLL interface section). The parameters
<I>Major</I> and <I>Minor</I> are the expected major and minor version numbers of the DLL (the actual major
and minor version numbers in the DLL itself are set using the <A HREF="$$LINK(DLL_VERSION)">DLL_VERSION</A> macro in the DLL
interface section). LoadDLL will refuse to load a DLL if the expected and actual version
numbers are not the same, or if the expected minor version number is greater than the actual minor
version number. As LoadDLL searches trough all folders for a matching DLL, it is completely
legal to have several DLLs with the same name (in different folders), but which differ in
their ID numbers or version numbers. LoadDLL will load the first DLL found (if any)
with a matching name, ID number and major version number, and whose minor version number
is greater or equal to the expected minor version number.
<BR><BR>
LoadDLL returns one of the following values:
<BR><BR>
<TABLE BORDER CELLPADDING="3">
<TR>
  <TD VALIGN="TOP">DLL_OK</TD>
  <TD>The DLL was loaded and initialized successfully.</TD>
</TR>
<TR>
  <TD VALIGN="TOP">DLL_NOTINGHOSTSPACE</TD>
  <TD>The DLL could not be loaded because the program counter is not in the "ghost space" (the
      virtual address space where HW2 protections do not take effect). Note that exe-packed
      programs are always executed in the ghost space; if you do not want to compress your program,
      you need to define
      <CODE><A HREF="$$INFOLINK(httigcc/advanced_ghostspace)">EXECUTE_IN_GHOST_SPACE</A></CODE>.</TD>
</TR>
<TR>
  <TD VALIGN="TOP">DLL_NOTFOUND</TD>
  <TD>The DLL is not found. This means that either a file with the name <I>DLLName</I> is not
      found in any folder, or such files exist, but none of them has the correct extension ('DLL'), the correct
      embedded signature, and the correct identification number (determined by the <I>ID</I> parameter).</TD>
</TR>
<TR>
  <TD VALIGN="TOP">DLL_LOCKFAILED</TD>
  <TD>The attempt to lock the DLL in memory has failed due to some strange reason. This error code
      is very unlikely.</TD>
</TR>
<TR>
  <TD VALIGN="TOP">DLL_OUTOFMEM</TD>
  <TD>There is not memory to load the DLL into RAM.</TD>
</TR>
<TR>
  <TD VALIGN="TOP">DLL_ALREADYLOADED</TD>
  <TD>There is already another DLL loaded in the RAM. Due to efficiency reasons, only one
      DLL is allowed to be loaded at the same time. You need to unload the current DLL using
      <A HREF="$$LINK(UnloadDLL)">UnloadDLL</A> before loading another one. Anyway, using more than
      one DLL is strongly deprecated if you don't know exactly what you are doing and why you are
      doing so.</TD>
</TR>
<TR>
  <TD VALIGN="TOP">DLL_WRONGVERSION</TD>
  <TD>There is at least one valid DLL file with the name <I>DLLName</I> and with the correct extension,
      signature, and identification number, but none of them has a major version number which is
      equal to the expected major number (determined by the <I>Major</I> parameter) and a minor version number
      which is greater or equal than the expected minor number (determined by the <I>Minor</I> parameter).</TD>
</TR>
</TABLE>
<BR>
Only if LoadDLL returns <A HREF="$$LINK(DLL_ErrorCodes)">DLL_OK</A>, it is valid to proceed further and to use functions imported
from the DLL. No further checking is done by the functions from the DLL, so your program will
definitely crash if you try to call any function from the DLL if LoadDLL has not returned <A HREF="$$LINK(DLL_ErrorCodes)">DLL_OK</A>.
Also, don't forget to call <A HREF="$$LINK(UnloadDLL)">UnloadDLL</A> when the DLL is not needed any more (usually at the end of
the program). So, any program which uses DLLs must have the following code fragment: 
<PRE>if ((status = LoadDLL (<I>DLLName</I>, <I>ID</I>, <I>Major</I>, <I>Minor</I>)) != DLL_OK)
{
  // <I>Perform some kind of error processing</I>
  // <I>and terminate the program in some way</I>
}

// <I>Proceed further</I>

UnloadDLL ();
</PRE>
You may use <A HREF="$$LINK(LoadDLLThrow)">LoadDLLThrow</A> instead, which
throws an error instead of returning an error code, but this means that you
can not determine what caused the problem. As another solution, you may use
<A HREF="$$LINK(error.h/ER_throw)">ER_throw</A> from
<A HREF="$$LINK(error.h/)">error.h</A> to throw your own error if loading the
DLL fails.
<BR><BR>
Typically, if you use functions which may throw errors, you can either catch
these errors using
<A HREF="$$LINK(error.h/TRY)">TRY</A>...<A HREF="$$LINK(error.h/ONERR)">ONERR</A>...<A HREF="$$LINK(error.h/ENDTRY)">ENDTRY</A>
blocks, or, if you want to <A HREF="$$INFOLINK(htretval/reterr)">pass them on to the AMS</A>, you
can use a single <A HREF="$$LINK(error.h/TRY)">TRY</A>...<A HREF="$$LINK(error.h/FINALLY)">FINALLY</A>...<A HREF="$$LINK(error.h/ENDFINAL)">ENDFINAL</A> block:
<PRE>if ((status = LoadDLL (<I>DLLName</I>, <I>ID</I>, <I>Major</I>, <I>Minor</I>)) != DLL_OK)
{
  // <I>Perform some kind of error processing</I>
  // <I>and terminate the program in some way</I>
}
TRY

  // <I>Proceed further</I>

FINALLY
  UnloadDLL ();
ENDFINAL
</PRE>
Or, using <A HREF="$$LINK(LoadDLLThrow)">LoadDLLThrow</A>:
<PRE>LoadDLLThrow (<I>DLLName</I>, <I>ID</I>, <I>Major</I>, <I>Minor</I>);
TRY

  // <I>Proceed further</I>

FINALLY
  UnloadDLL ();
ENDFINAL
</PRE>

[References]
Out=alloc.h/HeapAllocPtr, alloc.h/HeapDeref, alloc.h/HeapGetLock, alloc.h/HeapLock, alloc.h/HeapUnlock, mem.h/memcmp, string.h/strcmp, system.h/EX_patch, vat.h/SymFindFirst, vat.h/SymFindNext
In=LoadDLLThrow
