1
0
Fork 0
doc/devel/interface/interface-dynlibs.en.tm

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>