Dynamisch ladbare Bibliotheken

Die Kommunikation zwischen TeXmacs und einer Anwendung kann auSSer über eine „Pipeline“ auch dadurch erfolgen, dass die Anwendung als „dynamically linked library”, DLL, eingebunden wird. Pipelines sind meist leichter zu implementieren, oft sehr robust und flexibel in Bezug auf Daten, die nur nach und nach erzeugt werden. Aber DLLs sind schneller.

Um eine Anwendung dynamisch mit TeXmacs zu linken, sollten Sie dem TeXmacs Kommunikations-Protokoll folgen, das in folgenden Datei

  include/TeXmacs.h  

definiert ist.

Darin ist spezifiziert, dass die Anwendung folgende Datenstruktur exportieren soll:

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;

Sie enthält sowohl eine Installationsroutine für die Anwendung als auch eine Evaluierungsroutinen für zusätzliche Eingabe. (Mehr Informationen finden Sie in der Datei include/TeXmacs.h). TeXmacs exportiert folgende Struktur:

typedef struct TeXmacs_exports_1 {
  char* version_protocol; /* "TeXmacs communication protocol 1" */
  char* version_TeXmacs;
} TeXmacs_exports_1;

Jedes Programm hat für sein Speicher-Management selbst zu sorgen. Zeichenketten, die TeXmacs erzeugt, müssen von TeXmacs gelöscht werden. Das gilt entsprechend für die Anwendung.

Die Zeichenkette version_protocol sollte „TeXmacs communication protocol 1" und die Zeichenkette version_package die Version Ihrer Anwendung enthalten.

Die Funktion install wird ein einziges Mal von TeXmacs mit den Optionen options aufgerufen, um Ihre Anwendung zu initialisieren. Es überträgt die Routinen, die von TeXmacs exportiert werden, als TM. Diese Routine sollte, sofern erfolgreich, eine Statusmeldung zurückgeben, z.B.:

    "Ihre CAS-Version wurde erfolgreich in TeXmacs eingebunden"

Wenn die Installation ohne Erfolg blieb, sollten Sie NULL zurückgeben und *errors sollte eine erklärende Meldung enthalten.

Die evaluate-Funktion dient zur Evaluierung von what in einer TeXmacs-Sitzung mit dem Namen session. Sie sollte das Ergebnis der Evaluierung von what zurückgeben, falls erfolgreich, oder NULL, wenn ein Fehler auftrat. *errors kann, je nach Verlauf der Evaluierung, eine oder mehrere Warnungen enthalten oder eine Fehlermeldung, wenn die Evaluierung versagte. Die Formate sind die gleichen wie im Fall der Kommunikation über Pipelines.

Schließlich sollte die Konfigurations-Datei des Plugins noch so etwas wie das folgende enthalten:

(plugin-configure myplugin

(:require (url-exists? (url "$LD_LIBRARY_PATH" "libmyplugin.so")))

(:link "libmyplugin.so" "myplugin_exports" "")

further-configuration)

Hier ist myplugin_exports ein Zeiger auf eine Struktur vom Typ package_exports_1.

Bemerkung 1. Es ist möglich, dass das Kommunikations-Protokoll sich ändert. In diesem Fall werden die Daten-Strukturen TeXmacs_exports_1 und package_exports_1 durch TeXmacs_exports_n und package_exports_n ersetzt, worin n die Version des Protokolls ist. Diese Strukturen werden immer die abstrakten Strukturen TeXmacs_exports und package_exports behalten, in denen die Informationen über die Protokoll-, TeXmacs- und Anwendungs-Version, enthalten sind.

Das dynlink plugin

Das Beispiel Plugin dynlink zeigt, wie dynamisch ladbare Bibliotheken geschrieben und benutzt werden. Es besteht aus den Dateien:

    dynlink/Makefile
    dynlink/progs/init-dynlink.scm
    dynlink/src/dynlink.cpp

Das Makefile enthält die Zeilen

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

so dass dynlink.cpp zu einer dynamisch linkbaren Datei (DLL) dynlink/lib/libdynlink.so kompiliert wird. Die tmsrc Variable sollte so gesetzt sein, dass die include-Datei TeXmacs.h gefunden wird. Die Konfigurations-Datei init-dynlink.scm enthält die folgenden Zeilen

(plugin-configure dynlink

(:require (url-exists? (url "$LD_LIBRARY_PATH"

"libtmdynlink.so")))

(:link "libtmdynlink.so" "dynlink_exports" "")

(:session "Dynlink"))

Die C++ Datei dynlink.cpp enthält die Zeichenkette

static char* output= NULL;

mit der letzten Ausgabe, die Initialisierungs-Routine

char*
dynlink_install (TeXmacs_exports_1* TM, char* opts, char** errs) {
  output= (char*) malloc (50);
  strcpy (output, "\2verbatim:Started dynamic link\5");
  return output;
}

die Evaluierungs-Routine

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;
}

und die Daten-Struktur den Exporten

package_exports_1 dynlink_exports= {
  "TeXmacs communication protocol 1",
  "Dynlink 1",
  dynlink_install,
  dynlink_eval
};

Beachten Sie bitte, dass bei der Ausgabe die Anwendung für die Reservierung und die Freigabe von Speicher zu sorgen hat.

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".