mirror of https://github.com/texmacs/doc.git
255 lines
7.5 KiB
Tcl
255 lines
7.5 KiB
Tcl
<TeXmacs|1.0.3.7>
|
|
|
|
<style|tmdoc>
|
|
|
|
<\body>
|
|
<tmdoc-title|Dynamic libraries>
|
|
|
|
Instead of connecting your system to <TeXmacs> using a pipe, it is also
|
|
possible to connect it as a dynamically linked library. Although
|
|
communication through pipes is usually easier to implement, more robust and
|
|
compatible with gradual output, the second option is faster.
|
|
|
|
In order to dynamically link your application to <TeXmacs>, you should
|
|
follow the <TeXmacs> communication protocol, which is specified in the
|
|
following header file:
|
|
|
|
<\verbatim>
|
|
\ \ \ \ <simple-link|$TEXMACS_PATH/include/TeXmacs.h>
|
|
</verbatim>
|
|
|
|
In this file it is specified that your application should export a data
|
|
structure
|
|
|
|
<\cpp-fragment>
|
|
typedef struct package_exports_1 {
|
|
|
|
\ \ char* version_protocol; /* "TeXmacs communication protocol 1" */
|
|
|
|
\ \ char* version_package;
|
|
|
|
\ \ char* (*install) (TeXmacs_exports_1* TeXmacs,
|
|
|
|
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ char* options, char** errors);
|
|
|
|
\ \ char* (*evaluate) (char* what, char* session, char** errors);
|
|
|
|
} package_exports_1;
|
|
</cpp-fragment>
|
|
|
|
which contains an installation routine for your application, as well as an
|
|
evaluation routine for further input (for more information, see the header
|
|
file). <TeXmacs> will on its turn export a structure
|
|
|
|
<\cpp-fragment>
|
|
typedef struct TeXmacs_exports_1 {
|
|
|
|
\ \ char* version_protocol; /* "TeXmacs communication protocol 1" */
|
|
|
|
\ \ char* version_TeXmacs;
|
|
|
|
} TeXmacs_exports_1;
|
|
</cpp-fragment>
|
|
|
|
It is assumed that each application takes care of its own memory
|
|
management. Hence, strings created by <TeXmacs> will be destroyed by
|
|
<TeXmacs> and strings created by the application need to be destroyed by
|
|
the application.
|
|
|
|
The string <verbatim|version_protocol> should contain <verbatim|"TeXmacs
|
|
communication protocol 1"> and the string <verbatim|version_package> the
|
|
version of your package. The routine <verbatim|install> will be called once
|
|
by <TeXmacs> in order to initialize your system with options
|
|
<verbatim|options>. It communicates the routines exported by <TeXmacs> to
|
|
your system in the form of a pointer to a structure of type
|
|
<cpp-code|TeXmacs_exports_1>. The routine should return a status message
|
|
like
|
|
|
|
<\verbatim>
|
|
\ \ \ \ "yourcas-version successfully linked to TeXmacs"
|
|
</verbatim>
|
|
|
|
If installation failed, then you should return <verbatim|NULL> and
|
|
<verbatim|*errors> should contain an error message.
|
|
|
|
The routine <verbatim|evaluate> is used to evaluate the expression
|
|
<verbatim|what> inside a <TeXmacs>-session with name <verbatim|session>. It
|
|
should return the evaluation of <verbatim|what> or <verbatim|NULL> if an
|
|
error occurred. <verbatim|*errors> either contains one or more warning
|
|
messages or an error message, if the evaluation failed. The formats being
|
|
used obey the same rules as in the case of communication by pipes.
|
|
|
|
Finally, the configuration file of your plug-in should contain something as
|
|
follows:
|
|
|
|
<\scheme-fragment>
|
|
(plugin-configure <em|myplugin>
|
|
|
|
\ \ (:require (url-exists? (url "$LD_LIBRARY_PATH"
|
|
"lib<em|myplugin>.so")))
|
|
|
|
\ \ (:link "lib<em|myplugin>.so" "<em|myplugin>_exports" "")
|
|
|
|
\ \ <em|further-configuration>)
|
|
</scheme-fragment>
|
|
|
|
Here <verbatim|<em|myplugin>_exports> is a pointer to a structure of the
|
|
type <cpp-code|package_exports_1>.
|
|
|
|
<\remark>
|
|
It is possible that the communication protocol changes in the future. In
|
|
that case, the data structures <verbatim|TeXmacs_exports_1> and
|
|
<verbatim|package_exports_1> will be replaced by data structures
|
|
<verbatim|TeXmacs_exports_n> and <verbatim|package_exports_n>, where
|
|
<verbatim|n> is the version of the protocol. These structures will always
|
|
have the abstract data structures <verbatim|TeXmacs_exports> and
|
|
<verbatim|package_exports> in common, with information about the versions
|
|
of the protocol, <TeXmacs> and your package.
|
|
</remark>
|
|
|
|
<paragraph*|The <verbatim|dynlink> plug-in>
|
|
|
|
The <verbatim|dynlink> plug-in gives an example of how to write dynamically
|
|
linked libraries. It consists of the following files:
|
|
|
|
<\verbatim>
|
|
\ \ \ \ <example-plugin-link|dynlink/Makefile>
|
|
|
|
\ \ \ \ <example-plugin-link|dynlink/progs/init-dynlink.scm>
|
|
|
|
\ \ \ \ <example-plugin-link|dynlink/src/dynlink.cpp>
|
|
</verbatim>
|
|
|
|
The <verbatim|Makefile> contains
|
|
|
|
<\quotation>
|
|
<\framed-fragment>
|
|
<\with|par-par-sep|0fn>
|
|
<\with|font-family|tt>
|
|
tmsrc = /home/vdhoeven/texmacs/src/TeXmacs
|
|
|
|
CXX = g++
|
|
|
|
LD \ = g++
|
|
|
|
\;
|
|
|
|
lib/libtmdynlink.so: src/dynlink.cpp
|
|
|
|
\ \ \ \ \ \ \ \ $(CXX) -I$(tmsrc)/include -c src/dynlink.cpp -o
|
|
src/dynlink.o
|
|
|
|
\ \ \ \ \ \ \ \ $(LD) -shared -o lib/libtmdynlink.so src/dynlink.o
|
|
</with>
|
|
</with>
|
|
</framed-fragment>
|
|
</quotation>
|
|
|
|
so that running it will create a dynamic library
|
|
<verbatim|dynlink/lib/libdynlink.so> from <verbatim|dynlink.cpp>. The
|
|
<verbatim|tmsrc> variable should contain <verbatim|$TEXMACS_PATH>, so as to
|
|
find the include file <verbatim|TeXmacs.h>. The configuration file
|
|
<verbatim|init-dynlink.scm> simply contains
|
|
|
|
<\scheme-fragment>
|
|
(plugin-configure dynlink
|
|
|
|
\ \ (:require (url-exists? (url "$LD_LIBRARY_PATH"
|
|
|
|
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ "libtmdynlink.so")))
|
|
|
|
\ \ (:link "libtmdynlink.so" "dynlink_exports" "")
|
|
|
|
\ \ (:session "Dynlink"))
|
|
</scheme-fragment>
|
|
|
|
As to the <value|cpp> file <verbatim|dynlink.cpp>, it contains a string
|
|
|
|
<\cpp-fragment>
|
|
static char* output= NULL;
|
|
</cpp-fragment>
|
|
|
|
with the last output, the initialization routine
|
|
|
|
<\cpp-fragment>
|
|
char*
|
|
|
|
dynlink_install (TeXmacs_exports_1* TM, char* opts, char** errs) {
|
|
|
|
\ \ output= (char*) malloc (50);
|
|
|
|
\ \ strcpy (output, "\\2verbatim:Started dynamic link\\5");
|
|
|
|
\ \ return output;
|
|
|
|
}
|
|
</cpp-fragment>
|
|
|
|
the evaluation routine
|
|
|
|
<\cpp-fragment>
|
|
char*
|
|
|
|
dynlink_eval (char* what, char* session, char** errors) {
|
|
|
|
\ \ free (output);
|
|
|
|
\ \ output= (char*) malloc (50 + strlen (what));
|
|
|
|
\ \ strcpy (output, "\\2verbatim:You typed ");
|
|
|
|
\ \ strcat (output, what);
|
|
|
|
\ \ strcat (output, "\\5");
|
|
|
|
\ \ return output;
|
|
|
|
}
|
|
</cpp-fragment>
|
|
|
|
and the data structure with the public exports:
|
|
|
|
<\cpp-fragment>
|
|
package_exports_1 dynlink_exports= {
|
|
|
|
\ \ "TeXmacs communication protocol 1",
|
|
|
|
\ \ "Dynlink 1",
|
|
|
|
\ \ dynlink_install,
|
|
|
|
\ \ dynlink_eval
|
|
|
|
};
|
|
</cpp-fragment>
|
|
|
|
Notice that the application takes care of the memory allocation and
|
|
deallocation of <cpp-code|output>.
|
|
|
|
<tmdoc-copyright|1998--2002|Joris van der Hoeven>
|
|
|
|
<tmdoc-license|Permission is granted to copy, distribute and/or modify this
|
|
document under the terms of the GNU Free Documentation License, Version 1.1
|
|
or any later version published by the Free Software Foundation; with no
|
|
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
|
|
Texts. A copy of the license is included in the section entitled "GNU Free
|
|
Documentation License".>
|
|
</body>
|
|
|
|
<\initial>
|
|
<\collection>
|
|
<associate|language|english>
|
|
<associate|page-bot|30mm>
|
|
<associate|page-even|30mm>
|
|
<associate|page-odd|30mm>
|
|
<associate|page-reduce-bot|15mm>
|
|
<associate|page-reduce-left|25mm>
|
|
<associate|page-reduce-right|25mm>
|
|
<associate|page-reduce-top|15mm>
|
|
<associate|page-right|30mm>
|
|
<associate|page-top|30mm>
|
|
<associate|page-type|a4>
|
|
<associate|par-width|150mm>
|
|
<associate|sfactor|4>
|
|
</collection>
|
|
</initial> |