Tech Note 05a: Using Shared Libraries

June 19, 2005

© NS BASIC Corporation. All rights reserved.

There are two steps involved in using a shared library from within an NSBasic program:

  1. Load the library using LoadLibrary.
  2. Use the functions and subroutines within the library using object syntax with the name of the library.

Loading the Library

Before an NSBasic program can use a shared library, it must first load it using the LoadLibrary statement. The best place for this is the application's startup code.

   Syntax:
      LoadLibrary filename[, refname]
   Description:
      Filename is a file ending with a .inf extension that can be found in the
      Lib subdirectory, with the .inf extension being optional.  Refname is an
      optional variable name that will be used to refer to the library in
      subsequent calls to external procedures.  Calling LoadLibrary from the
      Project Startup Code ensures that a library will be accessible globally
      in your project.
   Examples: (NS Basic/Palm IDE)
      LoadLibrary "Mathlib"           'Uses Mathlib.inf, refname = mathlib
      LoadLibrary "Shortlib.inf"      'Uses Shortlib.inf, refname = shortlib
      LoadLibrary "newlib", "nl"      'Uses Newlib.inf, refname = nl

You can use the GetVersion(libName) function to return the version string in the TVER resource of any .prc file, including shared libraries. Not all shared libraries have TVER resources, but for those that do, you can use this to determine version information.

Using the Functions and Subroutines

Once the library has been loaded, you can access the functions and subroutines within the library by using the short name, if you provided one, or the long name (without the .inf), as follows:

libName.subName [parameter {, parameter}]
variable = libName.funcName ( [parameter {, parameter}] )

This is just like using an intrinsic subroutine or function, except that it uses a compound name made of the library name separated from the subroutine or function name with a period.

You can pass scalars of all types to shared libraries. You can also pass arrays of Short, Integer, Float, Double, and Byte to shared libraries, which may modify the values in the arrays. The best place to find out how to use a specific library is the documentation and examples that come with the library. If this documentation is missing or incomplete, you may need to figure it out.

If you pass a string to a shared library function or subroutine, and the function or subroutine can modify the contents of the string, you should first initialize the string to be as long as the largest possible return string. NSBasic will automatically expand strings to 300 bytes if they are shorter.

There are two versions of NSBasic shared libraries. Version 2 provides automatic type conversion and automatic passing by reference and is much safer to use. Version 1 does not. To determine the version of a shared library, locate its information file. The name of this file will end in .inf, and it should be in the Lib directory of the install folder (e.g. C:\NSBasic\Lib). Version 2 files contain a line InfVers=2.0

Due to the improvements in Version 2 shared libraries, using one is easy. Using subroutines and functions within a shared library just as you would use intrinsic or defined subroutines and functions should work. It is an error, however, to use a shared library function as a subroutine or a subroutine as a function. With Version 1 shared libraries, on the other hand, you must be extremely careful about what types you pass to shared libraries. The remainder of this section describes how to use Version 1 shared libraries, but it is good practice for using Version 2 shared libraries as well.

If you use literals, NS Basic/Palm will assume you mean certain data types. These are as follows:

Numbers without a decimal point 63 Int32
Numbers with a decimal point 1.5 double
Strings "Hello" Char *
Calculations (1/2) float (except when the result is 0)

It is much safer, however, only to use variables defined by Dim statements when passing parameters to shared library functions and subroutines. For scalar values, the following data types will be used:

Short Int16
Integer Int32
Float float (4-byte IEEE floating point)
Double double (8-byte IEEE floating point)
String Char * (null-terminated)
Byte unsigned char * (single-byte)
Variant void *

If a shared library function requires a char or Char parameter, you can pass it as a single Short.

Scalar types are normally passed by value, with the exception of strings and bytes, which are always passed by reference/pointer. You can also pass entire arrays of Byte, Short, Integer, Float, or Double.

The array mechanism also allows you to pass single parameters by reference/pointer. Declare an array using the Dim statement containing two or more elements of the desired data type. Use the first element as the value. (It is necessary to declare two or more elements because, at runtime, a single-element array is indistinguishable from a scalar.)