Creating a “C” Plugin
Prev
Next

## Creating a “C” Plugin

A Kst plugin consists of two files — an XML file and a shared object file.

### The XML 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 ``[modulename]`.xml`, where `[modulename]` is the value of the `name` attribute of the `modulename` node.

### The Shared Object File

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 succesfully, 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;
    }

### Compiling the Plugin

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.

Prev
Next
Home

Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team