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

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