Using wavevars() to Access PV-WAVE Variables
You can access PV‑WAVE variables from a C program by calling the function wavevars. Once commands have been sent to PV‑WAVE from an external application, you can use the wavevars function to access the results in the external application. wavevars is a C function that can be invoked from code linked to PV‑WAVE either:
statically via
cwavecdynamically via LINKNLOAD
note | Direct interaction between a FORTRAN program and wavevars is not possible because FORTRAN lacks C’s ability to access a common data area by address. Thus, to access PV‑WAVE variables from a FORTRAN program, a C wrapper must be written that calls wavevars. |
wavevars obtains data directly from PV‑WAVE’s variable data space.
note | See also the section
"Method 2: The Option Programming Interface". The Option Programming Interface (OPI) functions allow user-written code to access PV‑WAVE variables and use other PV‑WAVE functionality. OPI provides greater flexibility and control than wavevars. |
Usage
int argc;
char **argv;
WaveVariable *argp;
result = wavevars(&argc, &argv, &argp);
Parameters
argc—Set to the number of variables returned.
argv—Set to be an array of strings, sorted in lexicographic order, corresponding to variable names available at the current scope level of PV‑WAVE.
argp—A type WaveVariable array of descriptors defining the type, structure, and dimension of the variables as well as providing a pointer to their actual data. The WaveVariable structure is described in the Discussion section that follows.
Returned Value
result—A C int value which is nonzero if the routine executed successfully, and zero if an error (such as running out of memory) occurred.
Discussion
PV‑WAVE variables can be accessed directly from a C function by calling the C function wavevars which is linked into PV‑WAVE. The C function passes three parameters to the wavevars entry point.
The first parameter is the address of an integer variable into which wavevars will return the number of currently-defined PV‑WAVE variables (including system variables).
The second parameter is the address of an array of pointers to strings (i.e., char**) into which wavevars will return the names of currently-defined PV‑WAVE variables.
The third parameter is the address of an array of pointers to the C structure WaveVariable into which wavevars will return information regarding the type, structure, dimension, and data of each PV‑WAVE variable (including a pointer to the current value of the variable).
WaveVariable is defined as follows in $WAVE_DIR/util/variables/wavevars.h. This header file must be included in any C function that calls wavevars.
typedef struct WaveVariable {
int type;
int read_only;
int numdims;
int dims[8];
int numelems;
int *data;
char name[MAXIDLEN + 1];
} WaveVariable;
note | Although wavevars returns pointers to the data associated with PV‑WAVE’s variables, keep in mind that the data pointer associated with a given variable can change after execution of certain PV‑WAVE system commands. It’s best to call wavevars immediately before it is needed to obtain information from the external program. |
The wavevars function allocates space to store the information it returns to the caller. When the caller no longer needs the information returned by wavevars, then the free_wavevars() function should be called to free the space. The arguments to free_wavevars() should be identical to those used in the call to wavevars such as:
result = free_wavevars( &argc, &argv, &argp );
and argc must still contain the number of variables returned by the wavevars call.
The WaveVariable structure’s fields are:
int type—The type field indicates the type of the variable. Valid PV‑WAVE variable types, together with their C equivalents, are defined in wavevars.h as follows:
TYP_BYTE char;
TYP_INT short;
TYP_INT32 int;
TYP_LONG long;
TYP_FLOAT float;
TYP_DOUBLE double;
TYP_COMPLEX struct { float r, i; } COMPLEX;
TYP_DCOMPLEX struct { double r, i;} DCOMPLEX;
TYP_STRING char *;
In PV‑WAVE, a structure is a collection of data where each field (tag) has a name. The C structure WaveVariable describes a PV‑WAVE structure with a type of TYP_STRUCT, where each element of the structure is contained in a list of WaveVariable structures pointed to by the data field, which is described later in this section.
The constant TYP_ARRAY will be bitwise or-ed into the type field if the variable is in fact an array.
int read_only—Many PV‑WAVE variables are read-only, and thus if this field is nonzero, it is not permissible to alter the actual variable data. This is often the case with system variables.
int numdims—PV‑WAVE variables may be of dimension zero (scalar) to eight. The field numdims indicates the dimensionality of the variable.
int dims[8]—Indicates the size of each dimension of a variable if it is of type array.
int numelems—Corresponds to the total number of data values which are addressable from the data pointer.
int *data—Corresponds to the address of the actual variable data. The data is always stored as a one-dimensional C array regardless of the dimensionality of the PV‑WAVE variable.
char name[MAXIDLEN + 1]—Only used when the variable being described is of type structure and represents the structure or tag field name (depending on context).
To access a specific PV‑WAVE variable you must search the array of variable names returned by wavevars to find the index associated with that variable. Then use the index to access the correct PV‑WAVE variable from the WaveVariable array. The type field in WaveVariable is used to determine a variable’s type. To access the data associated with a PV‑WAVE variable it is necessary to use the data pointer and cast it to the correct type. It is then possible to read and/or modify the actual data value(s).
Example 1
The following is a simple program that retrieves a list of all PV‑WAVE variables and prints out their contents. The code fragment demonstrates several important concepts.
The data pointer must be cast to appropriate type.
The data is always stored as a flat one-dimensional array.
PV‑WAVE structures are stored recursively.
You can find the following listed file in:
$WAVE_DIR/demo/interapp/wavevars/example.c
#include <stdio.h>
#include "wavevars.h"
printallvars() /* display names, value of all WAVE vars */
{
int nvars, i;
char **names;
WaveVariable *vars;
if (wavevars(&nvars,&names,&vars)) {
for (i=0; i<nvars; i++) {
fprintf(stderr,"%s\n",names[i]);
printvar(& (vars[i]) );
fprintf(stderr,"\n");
}
free_wavevars(&nvars, &names, &vars);
}
}
printvar(v) /* print a WAVE variable on stderr */
WaveVariable *v;
{
if ( v->name )
fprintf(stderr,"\ttag: '%s'\n",v->name);
else
fprintf(stderr,"\ttag: \n");
if (v->read_only)
fprintf(stderr,"\tstat: READ_ONLY \n");
else
fprintf(stderr,"\tstat: READ/WRITE\n");
fprintf(stderr,"\tnelems: %d\n", v->numelems);
fprintf(stderr,"\tndims: %d\n",v->numdims);
fprintf(stderr,"\tdims:%d %d %d %d %d %d %d %d\n",
v->dims[0],v->dims[1],v->dims[2], v->dims[3],
v->dims[4],v->dims[5],v->dims[6], v->dims[7]);
printdata(v,v->numelems);
}
printdata(v,len)
WaveVariable *v;
int len;
{
int i;
if (v->type & TYP_ARRAY)
fprintf(stderr,"\ttype: ARRAY OF ");
else
fprintf(stderr,"\ttype: ");
switch(v->type & ~TYP_ARRAY) {
case TYP_BYTE:
{
char *b = ((char *)v->data);
fprintf(stderr,"BYTE\n");
fprintf(stderr, "\tdata: ");
for (i=0; i<len; i++)
fprintf(stderr, "%d ",(int)b[i]);
}
break;
case TYP_INT:
{
short *b = ((short *)v->data);
fprintf(stderr,"INTEGER\n");
fprintf(stderr, "\tdata: ");
for (i=0; i<len; i++)
fprintf(stderr, "%d ",(int)b[i]);
}
break;
case TYP_INT32:
{
int *b = ((int *) v->data);
fprintf (stderr, "INT32\n");
fprintf (stderr, "\tdata: ");
for (i = 0; i < len; i++)
fprintf (stderr, "%d ", b[i]);
}
break;
case TYP_LONG:
{
long *b = ((long *)v->data);
fprintf(stderr,"LONG\n");
fprintf(stderr, "\tdata: ");
for (i=0; i<len; i++)
fprintf(stderr, "%ld ",b[i]);
}
break;
case TYP_FLOAT:
{
float *b = ((float *)v->data);
fprintf(stderr,"FLOAT\n");
fprintf(stderr, "\tdata: ");
for (i=0; i<len; i++)
fprintf(stderr, "%g ",b[i]);
}
break;
case TYP_DOUBLE:
{
double *b = ((double *)v->data);
fprintf(stderr,"DOUBLE\n");
fprintf(stderr, "\tdata: ");
for (i=0; i<len; i++)
fprintf(stderr, "%g ",b[i]);
}
break;
case TYP_COMPLEX:
{
Complex *b = ((Complex *)v->data);
fprintf(stderr,"COMPLEX\n");
fprintf(stderr, "\tdata: ");
for (i=0; i<len; i++)
fprintf(stderr, "<%g,%g> ",b[i].r, b[i].i);
}
break;
case TYP_STRING:
{
char **b = ((char **)v->data);
fprintf(stderr,"STRING\n");
fprintf(stderr, "\tdata: ");
for (i=0; i<len; i++)
if ( b[i] )
fprintf(stderr, "'%s' ",b[i]);
}
break;
case TYP_STRUCT:
{
WaveVariable *b=((WaveVariable *) v->data);
fprintf(stderr,"STRUCTURE\n");
fprintf(stderr, "\tdata:");
for (i=0; i<len; i++) {
fprintf(stderr, "\n");
printvar(&(b[i]));
}
}
break;
}
}
Example 2
For an example that shows how to call PV‑WAVE and access its data space from a C program, see
"Example 3".
Example 3
For an example that shows how to call PV‑WAVE and access its data space from a FORTRAN program, see
"Example 3".
Example 4
For an example that shows how to call a C program from within PV‑WAVE and have the C program access PV‑WAVE’s variable data space, see
"Example 3".
Example 5
For an example that shows how to call a FORTRAN program from within PV‑WAVE and have the FORTRAN program access PV‑WAVE’s variable data space (via a C wrapper), see
"Example 4".
Version 2017.0
Copyright © 2017, Rogue Wave Software, Inc. All Rights Reserved.