A Kst plugin consists of two files — an XML file and a shared object file.
The XML file provide information about the plugin and describes its inputs and outputs. The following is an example of an XML file for a Kst plugin:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE Module SYSTEM "file:/Repository/Level2/Soft/ProC/moduledef.dtd"> <module> <intro> <modulename name="testplugin"/> <!-- The name of the module --> <author name="Rick Chern"/> <!-- The name of the author --> <description text="A test plugin for me"/> <!-- A description of the module --> <version minor="1" major="0"/> <!-- The version number of the module --> <state devstate="release"/> <!-- The development state of the module (optional)--> </intro> <interface> <!--inputs here--> <input> <table type="float" name="Input Vector 1" descr="The first input vector" /> </input> <input> <float name="Input Scalar 1" descr="The first input scalar" /> </input> <!--outputs here--> <output> <table type="float" name="Output Vector 1" descr="The first output vector" /> </output> <output> <float name="Output Scalar 1" descr="The first output scalar" /> </output> </interface> </module>
Generally, you can use the example above as a template and modify sections to fit your needs.
As can be seen from the example, the XML file consists of one module
node. The module
node has an intro
node and an
interface
node. You should modify the intro
node
appropriately using the comments in the above XML file as guides. It is important that
modulename
has the name
attribute set to the same name
that your shared object file will use.
The interface
node describes the actual inputs and outputs of the plugin.
Each input is described by an input
node, and each output is described
by an output
node. Each input or output should have either a
table
or a float
node as a child. The type
attribute of a table
must be set to "float"
.
Note that the order of the inputs and outputs matters — the order is used to determine
the index values for each input and output array of the object file, and is the same order
used to display the input and output fields in the Kst plugin interface.
Once you have completed the XML file, save it as
, where
[modulename]
.xml[modulename]
is the value of the name
attribute
of the modulename
node.
The shared object file contains the actual functionality of the plugin. In other words, it determines how to derive the outputs from the given inputs. The following are the requirements for the shared object file:
The object must export the following C linkage symbol:
int symbol(const double *const
inArrays[]
,
const int inArrayLens[]
,
const double inScalars[]
,
double *outArrays[]
,
int outArrayLens[]
,
double outScalars[]
)
where symbol
must be the value of the name
attribute
of the modulename
node in the XML file. This is the only
function that will be called by Kst (although you may have other functions).
The following describes each argument of this function:
const double *const inArrays[]
The array of input arrays. Each input array corresponds to an input vector.
The arrays are in the same order as the vectors are listed in the XML file, so
inArrays[0]
is the array representing the first input vector,
inArrays[1]
is the array representing the second input vector,
and so on.
const int inArraysLens[]
The array containing array lengths for each input array. The lengths are stored
in the same order as the arrays in inArrays[]
(e.g.
inArrayLens[0]
is the length of inArrays[0]
).
const double inScalars[]
The array of input scalars. The scalars are stored in the same order as they are listed in the XML file.
double *outArrays[]
The array of output arrays. Each output array corresponds to an output vector, and the arrays should be in the same order as the output vectors are listed in the XML file.
int outArrayLens[]
The array that should contain lengths of the output arrays. The lengths should be
stored in the same order as the arrays in outArrays[]
.
double outScalars[]
The array of output scalars. The scalars should be in the same order they are listed in the XML file.
The function must return 0
if it executed successfully, and
-1
otherwise.
The code for the object file must handle unexpected inputs, such as empty input arrays
(in most cases a return value of -1
would be sufficient when such
situations are encountered).
The number and type of outputs must be exactly as specified by the XML file.
You will probably need to resize the arrays in outArrays[]
.
To do so, use the realloc()
function. E.g.,
outArrays[0]=(double*)realloc(outArrays[0], 5*sizeof(double));
will allocate space for 5 doubles for outArrays[0]
. Do not
use any memory allocator other than realloc()
.
The input arguments must remain constant. Do not cast them to non-constant types.
The following is an example of the shared object file source code for a simple plugin:
#include <stdlib.h> extern "C" int testplugin(const double *const inArrays[], const int inArrayLens[], const double is[], double *outArrays[], int outArrayLens[], double outScalars[]); int testplugin(const double *const inArrays[], const int inArrayLens[], const double is[], double *outArrays[], int outArrayLens[], double outScalars[]) //Accept 1 vector and 1 scalar. Multiply all elements of the vector by the //scalar, and output the resulting vector. Also output the original scalar. { //Set the outputs outArrayLens[0]=inArrayLens[0]; //resize the output arrays outArrays[0]=(double*)realloc(outArrays[0], inArrayLens[0]*sizeof(double)); //multiply each element of the input vector //by the scalar for (int i=0; i<inArrayLens[0]; i++) { outArrays[0][i]=inArrays[0][i] * is[0]; } //now set the output scalar outScalars[0]=is[0]; return 0; }
If you are using gcc to compile your plugin, simply compile the object file:
cc -Wall -c -o myplugin.o myplugin.c -fPIC -DPIC
and then create the shared library:
ld -o myplugin.so -shared myplugin.o
The resulting *.so
file and *.xml
file must be put in the same
directory. When you use Kst's Plugin Manager to load the XML file, it will automatically look for the
shared object file in the same directory.
Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team