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.
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:
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:
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:
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:
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:
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
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:
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:
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:
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:
Parameters:
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.
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
.