DllLoad , DllUnload , DllEnumerate , StubApiCStart , StubApiCPrettyName , StubApiCPluginPurpose , StubApiCShortIntegerConstant , StubApiCInclude , StubApiCFunction , StubApiCRemark , StubApiCSetEnv , StubApiCFile , StubApiCStruct .

# The Yacas plugin structure

Yacas supports dynamically loading libraries at runtime. This chapter describes functions for working with plugins.

DllLoad | load a plugin
DllUnload | unload a plugin
DllEnumerate | enumerate all loaded plugins
StubApiCStart | begin a C++ plugin API description
StubApiCPrettyName | give a descriptive name for documentation
StubApiCPluginPurpose | document the purpose of the plugin
StubApiCShortIntegerConstant | declare integer constant in plugin
StubApiCInclude | declare include file in plugin
StubApiCFunction | declare C++ function in plugin
StubApiCRemark | provide more documentation for plugin
StubApiCSetEnv | access Yacas environment in plugin
StubApiCFile | set file name for plugin API
StubApiCStruct | declare C struct in plugin

The plugin feature allows Yacas to interface with other libraries that support additional functionality. For example, there could be a plugin enabling the user to script a user interface from within Yacas, or a specific powerful library to do numeric calculations.

The plugin feature is currently in an experimental stage, and it will not work on each platform. To be precise, the `libltdl` library is used to load the plugins. This will only work on platforms which are supported by `libltdl`, which includes Linux, Mac OS X, Solaris, and HP-UX.

The remainder of the section is only of interest to users who want to write plugins themselves. It is assumed that the reader is comfortable programming in C++.

In addition to the plugin structure in the Yacas engine, there is a module `cstubgen` (currently still under development) that allows a rapid creation of a plugin that interfaces to an external library. Essentially all that is required is to write a file that looks like the header file of the original library, but written in Yacas syntax. The module `cstubgen` is then able to write out a C++ file that can be compiled and linked with the original library, and then loaded from within Yacas. To include a function in the plugin typically takes one line of Yacas code. There are a few examples in the `plugins/` directory (the files ending with api.stub). The build system converts these automatically to the required C++ files.

In addition to the C++ stub file, `cstubgen` also automatically generates some documentation on the functions included in the stub. This documentation is put in a file with extension '.man.txt'.

An example describing the use of `cstubgen` can be found in the essay "Creating plugins for Yacas" . See Essays on Yacas, Chapter 5 for a description of the integration of plugins in the build system.

###

DllLoad -- load a plugin

##### Internal function

##### Calling format:

    DllLoad(file)

##### Parameters:

`file` -- file name of the plugin

##### Description:

`DllLoad` loads the plugin `file` into Yacas. Neither the directory nor the extension of `file` need to be specified. The result is `True` if the plugin is loaded successfully, and `False` otherwise.

If the argument `file` does not specify a directory, all directories in the path for Yacas plugins are searched. This path is built up by calls to `DllDirectory`. In addition, it contains the default plugin directory which is specified by the command line option `--dlldir` (see The Yacas User's Function Reference, Chapter 1 ). If this option is not present, the default plugin directory is as specified at compile time (the default value is `/usr/local/lib/yacas`).

If the argument `file` does not specify the extension, then first the extension `.la` is appended. This is the standard extension for Libtool libraries. If no plugin with this name can be found, a platform-specific extension is tried (as an example, this is `.so` on platforms with ELF libraries).

##### Example:

The following commands load the example plugin, and then call the function `AddTwoIntegers` which is defined in this plugin.

     In> DllLoad("example");
     Out> True
     In> AddTwoIntegers(2,3);
     Out> 5

Note that it suffices to specify the string `example`. Yacas knows that the plugin resides in the file `/usr/local/lib/yacas/example.la` (if plugins are installed in the default locations).

##### See also:

DllDirectory , DllUnload , DllEnumerate .

###

DllUnload -- unload a plugin

##### Internal function

##### Calling format:

    DllUnload(file)

##### Parameters:

`file` -- file name of the plugin

##### Description:

`DllUnload` unloads a plugin previously loaded with `DllLoad`. The argument `file` has to be exactly the same as specified in the call to `DllLoad`, or the system will not be able to determine which plugin to unload. It will scan all plugins which are currently loaded, and delete the first one found to exactly match.

`DllUnload` always returns `True`, even if no plugin with the name `file` is found.

##### Example:

First, we load the example plugin, and call the function `AddTwoIntegers` which is defined in this plugin.

    In> DllLoad("example");
    Out> True
    In> AddTwoIntegers(2,3);
    Out> 5

Then, we unload the plugin, and we check that the function `AddTwoIntegers` is indeed no longer defined.

    In> DllUnload("example");
    Out> True
    In> AddTwoIntegers(2,3);
    Out> AddTwoIntegers(2,3)

##### See also:

DllLoad , DllEnumerate .

###

DllEnumerate -- enumerate all loaded plugins

##### Internal function

##### Calling format:

    DllEnumerate()

##### Description:

`DllEnumerate` returns a list with the names of all the plugins which are currently loaded.

##### Example:

At startup, no plugins are loaded, so `DllEnumerate()` evaluates to the empty list.

    In> DllEnumerate();
    Out> {}

This changes after we load the example plugin.

    In> DllLoad("example");
    Out> True
    In> DllEnumerate();
    Out> {"example"}

##### See also:

DllLoad , DllUnload .

###

StubApiCStart -- begin a C++ plugin API description

##### Standard library

##### Calling format:

    StubApiCStart(name)

##### Parameters:

`name` -- string, name of the plugin

##### Description:

This function must be called to begin generating a stub file for linking a C or C++ library with Yacas. A stub specification file needs to start with this function call, to reset the internal state of Yacas for emitting a stub C++ file. The parameter `name` should identify the plugin uniquely.

##### See also:

StubApiCShortIntegerConstant , StubApiCInclude , StubApiCFunction , StubApiCFile , StubApiCSetEnv , StubApiCPrettyName .

###

StubApiCPrettyName -- give a descriptive name for documentation

##### Standard library

##### Calling format:

    StubApiCPrettyName(name)

##### Parameters:

`name` -- descriptive name of the plugin

##### Description:

This function sets a descriptive name for a plugin. It should be very short, for example, "plotting" or "XYZ library", and it should not contain the word "plugin".

This name is used for producing documentation. It will appear in the title of the documentation section describing the plugin.

##### Example:

    StubApiCPrettyName("multithreaded GUI")

The documentation section will be titled "The multithreaded GUI plugin".

##### See also:

StubApiCSStart , StubApiCPluginPurpose .

###

StubApiCPluginPurpose -- document the purpose of the plugin

##### Standard library

##### Calling format:

    StubApiCPluginPurpose(text)

##### Parameters:

`text` -- a short description of the plugin

##### Description:

The text should be in the reference manual plain text format. (See the documentation on the format .) It will be inserted after the section title in the plugin documentation.

##### See also:

StubApiCRemark , StubApiCPrettyName .

###

StubApiCShortIntegerConstant -- declare integer constant in plugin

##### Standard library

##### Calling format:

    StubApiCShortIntegerConstant(const,value)

##### Parameters:

`const` -- string representing the global variable to be bound runtime

`value` -- integer value the global should be bound to

##### Description:

define a constant 'const' to have value 'value'. The value should be short integer constant. This is useful for linking in defines and enumerated values into Yacas. If the library for instance has a define

    #define FOO 10

Then

    StubApiCShortIntegerConstant("FOO","FOO")

will bind the global variable FOO to the value for FOO defined in the library header file.

##### See also:

StubApiCStart , StubApiCInclude , StubApiCFunction , StubApiCFile , StubApiCSetEnv .

###

StubApiCInclude -- declare include file in plugin

##### Standard library

##### Calling format:

    StubApiCInclude(file)

##### Parameters:

`file` -- file to include from the library the plugin is based on

##### Description:

Declare an include file (a header file for the library, for instance) The delimiters need to be specified too. So, for a standard library like the one needed for OpenGL, you need to specify

    StubApiCInclude("\<GL/gl.h\>")

and for user include file:

    StubApiCInclude("\"GL/gl.h\"")

##### See also:

StubApiCStart , StubApiCShortIntegerConstant , StubApiCFunction , StubApiCFile , StubApiCSetEnv .

###

StubApiCFunction -- declare C++ function in plugin

##### Standard library

##### Calling format:

    StubApiCFunction(returntype,fname,args)
    StubApiCFunction(returntype,fname,
      fname2,args)

##### Parameters:

`returntype` -- return type of new function

`fname` -- function of built-in function

`fname2` -- (optional) function name to be used from within Yacas

`args` -- list of arguments to the function

##### Description:

This function declares a new library function, along with its calling sequence. `cstubgen` will then generate the C++ code required to call this function.

Return type, function name, and list of arguments should be literal strings (surrounded by quotes).

If `fname2` is not supplied, it will be assumed to be the same as fname.

The return types currently supported are "`int`", "`double`" and "`void`".

The argument values that are currently supported are "`int`", "`double`", and "`input_string`".

Argument types can be specified simply as a string referring to their type, like `"int"`, or they can be lists with an additional element stating the name of the variable: `{"int","n"}`. The variable will then show up in the automatically generated documentation as having the name "n".

##### Examples:

To define an OpenGL function `glVertex3d` that accepts three doubles and returns void:

    StubApiCFunction("void","glVertex3d",
      {"double","double","double"});

##### See also:

StubApiCStart , StubApiCShortIntegerConstant , StubApiCInclude , StubApiCFile , StubApiCSetEnv .

###

StubApiCRemark -- provide more documentation for plugin

##### Standard library

##### Calling format:

    StubApiCRemark(string)

##### Parameters:

`string` -- text to be added to the documentation

##### Description:

`StubApiCRemark` adds the text to the stub documentation file that gets generated automatically. The documentation is put in a `.man.txt` file while the input file is being processed, so adding a remark on a function just after a function declaration adds a remark on that function. The format of the text must be that of the reference manual source in plaintext, see documentation on the format .

##### See also:

StubApiCPrettyName , StubApiCPluginPurpose , StubApiCStart , StubApiCSetEnv , StubApiCFile .

###

StubApiCSetEnv -- access Yacas environment in plugin

##### Standard library

##### Calling format:

    StubApiCSetEnv(func)

##### Parameters:

`func` -- name of the function to call to set the environment variable

##### Description:

This function forces the plugin to call the function func, with as argument `LispEnvironment&` `aEnvironment`. This lets the plugin store the environment class (which is needed for almost any thing to do with Yacas), somewhere in a global variable. aEnvironment can then be used from within a callback function in the plugin that doesn't take the extra argument by design.

There needs to ba a function in the plugin somewhere of the form

    static LispEnvironment* env = NULL;
    void GlutSetEnv(LispEnvironment& aEnv)
    {
        env = &aEnv;
    }

Then calling

    StubApiCSetEnv("GlutSetEnv");

will force the plugin to call `GlutSetEnv` at load time. All functions in the plugin will then have access to the Yacas environment.

##### See also:

StubApiCStart , StubApiCShortIntegerConstant , StubApiCInclude , StubApiCFunction , StubApiCFile .

###

StubApiCFile -- set file name for plugin API

##### Standard library

##### Calling format:

    StubApiCFile(pluginname,basename)

##### Parameters:

`pluginname` -- name of the plugin, as passed to `DllLoad`

`basename` -- name for the generation of the stub file

##### Description:

Generate the C++ stub file, "basename.cc", and a documentation file named "basename.description". The descriptions are automatically generated while adding functions and constants to the stub.

`pluginname` should be the name as passed to `DllLoad`. If the plugin name is loaded with `DllLoad("example")`, then pluginname should be `"example"`.

##### See also:

StubApiCStart , StubApiCShortIntegerConstant , StubApiCInclude , StubApiCFunction , StubApiCSetEnv .

###

StubApiCStruct -- declare C struct in plugin

##### Standard library

##### Calling format:

    StubApiCStruct(name)
    StubApiCStruct(name,freefunction)

##### Parameters:

`name` -- name of structure

`freefunction` -- function that can be called to clean up the object

##### Description:

`StubApiCStruct` declares a `struct` in a specific library. The name should be followed by an asterisk (clearly showing that it is a pointer). After that, in the stub API definition, this type can be used as argument or return type to functions to the library.

By default the struct will be deleted from memory with a normal call to `free(...)`. This can be overridden with a function given as second argument, freefunction. This is needed in the case where there are additional operations that need to be performed in order to delete the object from memory.

##### Examples:

In a library header file, define:

    typedef struct SomeStruct
    {
      int a;
      int b;
    } SomeStruct;

Then in the stub file you can declare this struct by calling:

    StubApiCStruct("SomeStruct*")

##### See also:

StubApiCFunction .