Article # 101, added by Geoworks, historical record
| first | previous | index | next | last |

Dynamically Loading Libraries





Using Dynamically Loaded Libraries
==================================
Calling routines from dynamically loaded libraries is quite easy.  
The basics are all there is to it, so once you learn the basics, 
you've learned to use DLL routines.  The three main steps are:
1. call GeodeUseLibrary to load the library and get its handle
2. access the library routines
3. release the library with GeodeFreeLibrary.


Setup
-----
These two lines should be added to your .GOC file
#include
@include  /* the header file for your library, if it exists */

In your .GP file, add the line
library mylib noload   # "mylib" is the name of your library


GeodeUseLibrary
---------------
Pass the (DOS style) name of the library, the major and minor protocol
numbers of that library, and a pointer to a GeodeLoadError structure.
You need to set the working directory to that of the library.  In most
cases, the library is in the System directory.


Calling the library routines
----------------------------
ProcGetLibraryEntry
ProcCallFixedOrMovable_cdecl or ProcCallFixedOrMovable_pascal

To access the routines in the library, you must first get the pointer
to the routine using ProcGetLibraryEntry().  Then call the routine
with one of the two ProcCallFixedOrMovable_...() routines.  Geoworks
library routines are always declared as _pascal, so you should use
ProcCallFixedOrMovable_pascal on them.  You can find out for sure
whether the routine is _pascal or _cdecl by looking it up in the 
header file (grep for the routine name in the Include directory).

You can determine the entryNumber (second parameter of ProcGetLibraryEntry)
from the "export" lines in the library's .GP file.  The first line
corresponds to zero, with the values increasing by one for each successive
line.  If the creator of the library has #defined these values in the
library's .H (or .GOH) file, you could include this in your application's
source file and use these definitions for the entryNumber parameter.


GeodeFreeLibrary
----------------
If you dynamically load the library, then it is your responsibility to
free the library.  This is done simply by calling GeodeFreeLibrary().


Example
-------
    #define MY_LIB_ROUTINE_A  0
    #define MY_LIB_ROUTINE_B  1
    #define MY_LIB_ROUTINE_C  2
    #define MY_LIB_ROUTINE_D  3

    #if ERROR_CHECK
    static char *myLibName = "mylibec.geo";
    #else
    static char *myLibName = "mylib.geo";
    #endif

    GeodeHandle    myLibHandle;
    GeodeLoadError err;
    dword          returnValue;
    
    /* First store the current setting of the standard path and then set it
     * to the system directory, where all the library geodes should be. */
    FilePushDir();
    FileSetStandardPath(SP_SYSTEM);

    (myLibHandle = GeodeUseLibrary(myLibName, 0, 0, &err);

    if(myLibHandle != NullHandle)
    {
        returnValue = ProcCallFixedOrMovable_cdecl(
            ProcGetLibraryEntry(myLibHandle, MY_LIB_ROUTINE_A),
            /* library routine parameters go here */);
    }

    /* Restore the previous standard path setting. */
    FilePopDir();


Additional Information
----------------------
GeodeLoadErrors 
  GLE_PROTOCOL_IMPORTER_TOO_RECENT
  GLE_PROTOCOL_IMPORTER_TOO_OLD 	
  GLE_FILE_NOT_FOUND 		
  GLE_LIBRARY_NOT_FOUND 		
  GLE_FILE_READ_ERROR 		
  GLE_NOT_GEOS_FILE 		
  GLE_NOT_GEOS_EXECUTABLE_FILE 	
  GLE_ATTRIBUTE_MISMATCH 		
  GLE_MEMORY_ALLOCATION_ERROR 	
  GLE_NOT_MULTI_LAUNCHABLE 	
  GLE_LIBRARY_PROTOCOL_ERROR 	
  GLE_LIBRARY_LOAD_ERROR 		
  GLE_DRIVER_INIT_ERROR 		
  GLE_LIBRARY_INIT_ERROR 		
  GLE_DISK_TOO_FULL 		
  GLE_FIELD_DETACHING		
  GLE_INSUFFICIENT_HEAP_SPACE