Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Loading a library at run time

A library linked when the program is built must be present for the program to start at all. dylibload opens a shared library while the program runs, so the program can decide what to do when a plugin or an optional library is missing.

'' Load a library while the program runs, and find a function in it.
#if defined( __FB_WIN32__ )
    const LIBNAME = "ucrtbase.dll"
#elseif defined( __FB_DARWIN__ )
    const LIBNAME = "libm.dylib"
#else
    const LIBNAME = "libm.so.6"
#endif

type MathFn as function cdecl( byval x as float64 ) as float64

dim as any ptr lib_ = dylibload( LIBNAME )
if lib_ = nullptr then
    print "could not load the maths library"
    end 1
end if

'' dylibsymbol returns an address, or nullptr for a name it lacks.
dim as MathFn root = dylibsymbol( lib_, "sqrt" )
dim as MathFn missing = dylibsymbol( lib_, "no_such_function" )
print "found sqrt: "; cbool( root <> nullptr )
print "found no_such_function: "; cbool( missing <> nullptr )

if root <> nullptr then
    print "sqrt( 144 ) ="; root( 144.0 )
end if

'' A library that is not there is a null handle, not a crash.
print "missing library loads: "; _
      cbool( dylibload( "no_such_library_here" ) <> nullptr )

dylibfree( lib_ )

Output

found sqrt: true
found no_such_function: false
sqrt( 144 ) = 12
missing library loads: false
CallDoes
dylibload( name )opens the library and returns a handle, or nullptr
dylibsymbol( handle, "name" )finds a function or variable by name and returns its address, or nullptr
dylibfree( handle )closes the library

Library names differ by platform: name.dll on Windows, libname.so on Linux, often with a version number as in libm.so.6, and libname.dylib on macOS. The example loads the C runtime's maths library on each, chosen with #if defined( __FB_WIN32__ ) and its #elseifs, and calls its sqrt.

dylibsymbol returns an untyped address. Assigning it to a variable of a function pointer type, here MathFn, makes it callable, and that type is a promise exactly as a declare is: nothing checks it. A plugin system usually agrees on one entry point with a fixed signature, looks that up, and gets everything else through it.

After dylibfree, every address taken from the library is invalid. Look a symbol up once and keep the pointer while the library is open; the search costs time.

Activities

  1. Look up cbrt as well and print the cube root of 27.
  2. Make the program print a message and carry on when the library is missing, instead of ending.