LINKNLOAD Function
Provides simplified access to external routines in shareable images and Dynamic Link Libraries (DLLs).
Usage
result = LINKNLOAD(object, symbol[, param1, ..., paramn])
Input Parameters
object—A string specifying the filename, optionally including file path, of the DLL or shared object file to be linked and loaded.
symbol—A string specifying the function name symbol entry point to be invoked in the DLL or shared object file.
parami—(optional) The data to be passed as a parameter to the function. Any data type except structure can be used.
Returned Value
result—A scalar whose default is assumed to be of type longword unless it is specified with one of the keywords described below.
Keywords
D_Value—Specifies that the returned scalar is of type double-precision floating point.
F_Value—Specifies that the returned scalar is of type single-precision floating point.
Nocall—If present and nonzero, LINKNLOAD will not call the function defined by the object and symbol parameters. LINKNLOAD will try to find the object module and load it. Thus, you can use this keyword to do just the loading of the object module. If used with Unload, the object module is unloaded without calling the function. This is useful because you can recompile the object module, unload the old object module, and reload the new one without exiting the PV‑WAVE session.
S_Value—Specifies that the returned scalar is of type string.
Unload—If present and nonzero, LINKNLOAD unloads the object module immediately before returning from the LINKNLOAD command.
Value—(byte array) Allows you to specify which parameters should be passed by value, instead of by reference, which is the default. Value must be a byte array with one element for each parameter in the call. A parameter is passed by value if the corresponding byte in the Value array is non-zero. Array parameters must always be passed by reference.
Verbose—If present and nonzero, LINKNLOAD prints status information when an object module is being loaded or unloaded.
Discussion
LINKNLOAD provides a simple, yet powerful, mechanism for dynamically invoking your own code from PV-WAVE on all of its supported operating systems.
 
note
The LINKNLOAD function provides access to external routines in Dynamic Link Libraries (DLLs) and shared libraries. LINKNLOAD calls a function in the library and returns a scalar value. Parameters are passed through PV-WAVE to the function by reference, allowing the function to alter the value of PV-WAVE variables. It is the simplest method for attaching your own C and Fortran code to PV-WAVE.
Parameters are passed through PV-WAVE to the specified external function by reference, thus allowing the external function to alter values of PV-WAVE variables.
 
note
Be careful to ensure that the number, type, and dimension of the parameters passed to the external function match what it expects (this can most easily be done from within PV-WAVE before calling LINKNLOAD). Furthermore, the length of string parameters must not be altered and multi-dimensional arrays are flattened to one-dimensional arrays.
Accessing the Data in PV-WAVE Variables
Two methods exist for accessing the results generated by PV-WAVE in a user-written application called with LINKNLOAD.
One of these methods is to use the wavevars function and the other is to use the C-callable or FORTRAN-callable programming interface.
 
note
For more detailed information on these methods, see the PV‑WAVE Application Developer’s Guide.
Programming Notes
 
note
For AIX, the symbol entry point must be specified when the external shareable object is built, by using the -e flag, and thus the function symbol parameter to LINKNLOAD has no effect on AIX.
If you run PV‑WAVE and call LINKNLOAD and then relink your C function (or C wrapper) and try to call LINKNLOAD again in the same session, PV‑WAVE will crash. You must exit and then re-run PV-WAVE for the newly linked C routine to work.
Variables that are shared between PV‑WAVE and a C function must be created by PV‑WAVE and their size can not be modified by the C function.
It is possible to pass a constant as a parameter to a C function from PV‑WAVE via LINKNLOAD, but of course the C function can not pass a value back via that parameter.
Although wavevars returns pointers to the data associated with PV‑WAVE’s variables, it should be kept in mind that these addresses must be treated as “snapshots” because the data pointer associated with a particular PV‑WAVE variable may change after execution of certain PV‑WAVE system commands.
Using LINKNLOAD, care must be taken to ensure that the number, type, and dimension of the parameters passed to the function match what the function expects (this can most easily be done from within PV‑WAVE before calling LINKNLOAD). Furthermore, the length of string parameters must not be altered and multi-dimensional arrays are flattened to one-dimensional arrays.
UNIX Examples
The following PV-WAVE code demonstrates how to invoke a C function using LINKNLOAD. For more information on compiling shareable objects, see the PV‑WAVE Application Developer’s Guide.
In this example, parameters are passed to the C external function using the conventional (argc, argv) UNIX strategy. argc indicates the number of data pointers which are passed from PV-WAVE within the array of pointers called argv. The pointers in argv can be cast to the desired type as the following program demonstrates.
You can find the following listed file in:
$WAVE_DIR/demo/interapp/linknload/example.pro.
 
PRO example
 
; Define variables for the shared object and symbol parameters
; for LINKNLOAD.
object = 'example'
objectd = object
objectf = object
objects = object
symbol = 'WaveParams'
symbold = 'WaveParamsD'
symbolf = 'WaveParamsF'
symbols = 'WaveParamsS'
 
; Setup object and symbol names.
object = './' + object + '.so'
objectd = object
objectf = object
objects = object
 
 
; Use LINKNLOAD to run the example
ln = LINKNLOAD(object, symbol, BYTE(1), 2, 23i, LONG(3), $
FLOAT(4), DOUBLE(5), COMPLEX(6,7), 'eight')
INFO,ln
 
ln = LINKNLOAD(object, symbol, [BYTE(1)], [[2,3],[4,5]], $
[[2i,3],[4,5]], [LONG(3)], [FLOAT(4)], [DOUBLE(5)], $
[COMPLEX(6,7)], ['eight'])
INFO,ln
 
ln = LINKNLOAD(object, symbol, [BYTE(1)], [2], [23i], $
[LONG(3)], [FLOAT(4)], [DOUBLE(5)], [COMPLEX(6,7)], $
['eight'])
INFO,ln
 
ln = LINKNLOAD(objectd, symbold, BYTE(1), 2, INT32(23), $
LONG(3), FLOAT(4), DOUBLE(5), COMPLEX(6,7), 'eight', $
/D_VALUE)
INFO,ln
 
ln = LINKNLOAD(objectf, symbolf, BYTE(1), 2, 23i, LONG(3), $
FLOAT(4), DOUBLE(5), COMPLEX(6,7), 'eight', /F_VALUE)
INFO,ln
 
ln = LINKNLOAD(objects,symbols, BYTE(1), 2, 23i, LONG(3), $
FLOAT(4), DOUBLE(5), COMPLEX(6,7), 'eight', /S_VALUE)
INFO,ln
 
END
Accessing the External Function with LINKNLOAD
The following PV‑WAVE code demonstrates how the C function defined in the previous discussion could be invoked.
ln = LINKNLOAD(object, symbol, BYTE(1), 2, 23i, LONG(3), $
FLOAT(4), DOUBLE(5), COMPLEX(6,7), 'eight')
The resulting output is:
1 2 23 3 4.000000 5.000000 <6.000000,7.000000i> eight
Using the INFO command, you can see that LINKNLOAD returns the scalar value 12345, as expected.
INFO, ln
LN     LONG     =     1
The example program works with both scalars and arrays since the actual C program above only looks at the first element in the array and since PV‑WAVE collapses multi-dimensional arrays to one-dimensional arrays:
ln = LINKNLOAD(object, symbol, [BYTE(1)], [[2,3],[4,5]], $
[[2i,3],[4,5]], [LONG(3)], [FLOAT(4)], [DOUBLE(5)], $
[COMPLEX(6,7)], ['eight'])
The resulting output is:
1 2 2 3 4.000000 5.000000 <6.000000,7.000000i> eight
Using the INFO command:
INFO,ln
The resulting output is:
LN              LONG      =            1
For the following:
ln = LINKNLOAD(object, symbol, [BYTE(1)], [2], [23i], $
[LONG(3)], [FLOAT(4)], [DOUBLE(5)], [COMPLEX(6,7)], $
['eight'])
The resulting output is:
1 2 23 3 4.000000 5.000000 <6.000000,7.000000i> eight
Using the INFO command:
INFO,ln
The resulting output is:
LN              LONG      =            1
For the following:
ln = LINKNLOAD(objectd, symbold, BYTE(1), 2, INT32(23), $
LONG(3), FLOAT(4), DOUBLE(5), COMPLEX(6,7), 'eight', $
/D_VALUE)
The resulting output is:
1 2 23 3 4.000000 5.000000 <6.000000,7.000000i> eight
Using the INFO command:
INFO,ln
The resulting output is:
LN              DOUBLE    =        1.2345679
For the following:
ln = LINKNLOAD(objectf, symbolf, BYTE(1), 2, 23i, LONG(3), $
FLOAT(4), DOUBLE(5), COMPLEX(6,7), 'eight', /F_VALUE)
The resulting output is:
1 2 23 3 4.000000 5.000000 <6.000000,7.000000i> eight
Using the INFO command:
INFO,ln
The resulting output is:
LN              FLOAT     =       1.23450
For the following:
ln = LINKNLOAD(objects,symbols, BYTE(1), 2, 23i, LONG(3), $
FLOAT(4), DOUBLE(5), COMPLEX(6,7), 'eight', /S_VALUE)
The resulting output is:
1 2 23 3 4.000000 5.000000 <6.000000,7.000000i> eight 
Using the INFO command:
INFO,ln
The resulting output is:
LN              STRING    = '12345'
Windows Examples
Example programs showing how LINKNLOAD is used to pass parameters from PV-WAVE to an external C function and return results to PV-WAVE can be found in the directory:
(WIN) <wavedir>\demo\interapp\win32\linknload
Where <wavedir> is the main PV-WAVE directory.
This directory contains an example C program, a PV-WAVE procedure file, a makefile, and a README file. See the README file for details on running the example.
For more information on the example and on LINKNLOAD, see the PV‑WAVE Application Developer’s Guide.
See Also
Using wavevars() to Access PV-WAVE Variables (in the PV‑WAVE Application Developer’s Guide)