There are two kinds of user-defined functions:
ChainLink script functions must be contained in text files with a .m or .ch extension. The name of the function must coincide exactly with the file name. For example, the following script returns the minumum and maximum values in an array: % contents of min_and_max.ch or min_and_max.m function [minval, maxval] = min_and_max(X) minval=min(X(:)); maxval=max(X(:));
The syntax of a ChainLink script is meant to be compatible with Matlab syntax, although some differences may exist.
ChainLink will run any script that is in a subdirectory of the $CHAINLINK_DIR/lib folder. Otherwise, if a script is not in a subdirectory of the "lib" folder, then the script can only be run if it is located in the the current working directory.
While writing script functions is the easiest way to add custom functionality to ChainLink, functions involving intensive or highly specialized computation should be included in a C/C++ function whenever possible.
To make your C/C++ functions available from within ChainLink, you must must add your code to a dynamically loaded ChainLink plugin library (don't worry, it's a straightforward procedure). If you plan to use your own data structures or access external libraries or sourcecode, then you should first create your own library. See the section on creating a plugin library below.
For example, the following shows the ChainLink syntax for defining the square root function:
Declaration of square root in header file (real_library.h):
Definition of square root in source file (real_library.cpp)
For detailed instructions see the section on defining a C/C++ function below.
To create a new library, select Add new library from the Library menu, and provide a name for your new library (suppose you chose "my_example_library"). ChainLink will create a folder in the $CHAINLINK_DIR/lib directory called my_example_library. It will contain the following three files:
In addition to declarations for your functions, the header file will contain some special ChainLink syntax (found in C++ comment lines):
For more details on this syntax, see the secton on defining a C/C++ function below.
The file my_example_library.cpp is a standard C++ source file implementing the functions declared in the header.
The file my_example_library.pro is a standard Qt project file. You are free to put in your own options, include your own files and dependencies, and link to arbitrary libraries. Just make sure that the config includes the "dll" option and that the following line appears at the top of your .pro file:include($$(CHAINLINK_DIR)/chainlink.pri)
Although you are free to use your own C++ classes and data types (see section on adding a user-defined data type below), it is important to use the ChainLink's fundamental data types whenever possible.
Here are the steps involved in defining a new C/C++ function. If everything is installed properly, this should be painless.
Step 1: Select the library that you want to add the function to (or create a new library). Right click on the library in the ChainLink library view and choose "Edit header" (alternatively you can edit the header file in your own source code editor).
Step 2: Specify the function name, input parameters, output parameters, and a description of your function using the following syntax in the header file://[function] my_function_name //input: datatype1 paramname1, datatype2 paramname2, ..., datatype[n] paramname[n] //output: outtype1 outname1, outtype2 outname2, ..., outtype[m] outname[m] //description: description of my function goes here bool my_function_name(outtype1 &outname1, outtype2 &outname2, ..., outtype[m] &outname[m], datatype1 dataname1, datatype2 dataname2, ..., datatype[n] dataname[n]).
Important: Whenever possible, use ChainLink's fundamental data types for input and output parameters. You may also use your own data types as long as you have added them using the procedure below.
Step 3: (Edit the source file.) Save your changes to the header file, right click on the library and choose "Edit source" (or use your own source code editor). In the source file, simply implement the C++ function declared in the previous step. Be sure to set the values of all output parameters, and return true if no error occurred. In case of an error, use printf or cout statements to describe the error and return false.
Step 4: (Compile) Be sure to save the changes you made to the header and source files. Right click on the library and choose "Update and compile". If there are no errors,
The basic ChainLink data types (defined in chainlink_base/chainlink_base.h) are:integer -- long integer
Note: if your data type is a Qt Widget, see the section below on using Qt Widgets.
To make your C++ class or structure available from within ChainLink, simply use the following syntax in a library header file://[datatype] my_datatype_name
There are only two requirements for this data type:
Make sure that you either define your data type within the library header file or use a #include to the file that defines your class or structure.
Note: User-defined data types should only be defined once... do not define the same data type in more than one plugin library.
If you would like to launch a Qt Widget from chainlink simply do call the show() or showNormal() function of your widget from within your user-defined function.
*** Be sure to add config += qt in the project file for your library
*** It is often useful to use setAttribute(Qt::WA_DeleteOnClose) for your Widget
If you want to return a handle to your Widget within ChainLink, no problem... See how it's done by looking at the code for the qwidget_library. More documentation to come later. Or email the author with your questions.