3. Fragen zu UniScript

3.1. Ich habe eine Funktion in einer UniScript-Datei geändert. Was muß ich beachten ?

Wenn ich UniPlot neu starte, sind die Änderungen weg, obwohl in der UniScript-Datei die Änderungen noch vorhanden sind. Wo ist das Problem?

Beim Start von UniPlot wird eine Library geladen, die alle UniScript-Funktionen enthält. Die Library hat den Namen rs_sl.icl und befindet sich im Verzeichnis UniPlot\Program. Um eine neue Library zu erzeugen, wählen Sie den Befehl Extras=>UniScript Library erzeugen.

3.2. Wie kann eine einfache Dialogbox mit UniScript erzeugt werden?

The following example uses the function DialogBox to create a dialog box with two text fields.

The user input will be saved with the WriteProfileString function. When the My_GetEngineData function is called, the last input is used to initialize the dialog box.

def My_GetEngineData()
{
    ssEngineType = GetProfileString("Enginedata", "Type");
    ssEngineNo = GetProfileString("Enginedata", "No");
    ssTemplate = ["Engine Type: |              |",...
                  "Engien No:   |              |"]
    svRet=DialogBox(ssTemplate,[ssEngineType, ssEngineNo], "Engine Data");
    if (svRet[1] == "DLG_CANCEL") {
        return "DLG_CANCEL";
    }
    WriteProfileString("Enginedata", "Type", svRet[1]);
    WriteProfileString("Enginedata", "No", svRet[2]);
    return svRet;
}

The following example shows how you can use the function in your program:

svEngineData = My_GetEngineData();
if (svEngineData[1] != "DLG_CANCEL") { // Was the Cancel button selected ?
    auto_ReplaceText("$EngineType$", svEngineData[1]);
    auto_ReplaceText("$EngienNo$", svEngineData[2]);
}

3.3. The UniScript function system doesn’t work perfectly, how can I execute a command ?

Missing

3.4. Wie kann man eine DLL schreiben und eine Funktion daraus mit UniScript aufrufen ?

Hier sehen Sie eine einfache C-Funktion die prüft, ob ein Array von Zahlen aufsteigend sortiert ist, ob also p[0] kleiner oder gleich p[1] usw. ist. Man könnte diese Funktion natürlich auch einfach in UniScript direkt schreiben, aber die C-Funktion soll ja nur ein Beispiel sein.

// monoton.c
// checks if p is increasing: p0 <= p1 <= .. <= pn
int monoton(double *p, int n)
{
    int i, n1;

    n1 = n-1;
    for (i = 0; i < n1; i++) {
        if (p[i+1] <= p[i])
            return 0;
    }
    return 1;
}

Falls Sie mit dem Microsoft-C Compiler eine DLL (Dynamische Link Library) aus dieser Funktion erzeugen wollen, benötigen Sie noch ein Linker-Definitionsfile.

LIBRARY monoton
EXPORTS
monoton @1

Beim Microsoft-C Compiler können Sie aus diesen beiden Dateien nun mit folgendem Aufruf die Datei monoton.dll erstellen. Bei anderen Compilern mag der Aufruf ein wenig anders aussehen. Schauen Sie dazu in die Dokumentation des Compilers.

CL /LD monoton.c monoton.def

Anmerkung:

1.) Falls es sich bei der Datei um eine C++-Datei handelt, müssen die Funktionen als extern "C" deklariert werden.

Beispiel:

extern "C" int monoton(double *p, int n);

2.) Anstatt einer Linker-Definitions-Datei (*.def) können Sie die Funktionen auch folgendermaßen deklarieren:

extern "C" __declspec(dllexport) int monoton(double *p, int n);

Die C-Funktion kann nun getestet werden. Die Funktion RegisterFunction muss verwendet werden um die Funktion in der DLL UniScript bekannt zu machen. Manche C-Compiler hängen übrigends einen Unterstrich vor den Funktionsnamen. Schreiben Sie dann den zweiten Parameter von RegisterFunction als "_monoton".

// monoton.ic
nRet = RegisterFunction("monoton.dll", "monoton", ..
                        "int", "monoton", ["double *p", "int n"])
if (nRet <= 0) MessageBox(sprintf("Error: %d", nRet));
// sichere Hülle
def IsMonoton(v)
{
    if (isreal(v) == FALSE) {
        error("need a real vector");
    }
    return monoton(v, len(v));
}
// Beispiel-Aufrufe: Kopieren Sie diese Zeilen
// in das UniScript-Kommandofenster:
IsMonoton(1)
IsMonoton([1,2,3,8])
IsMonoton([1,2,3,2])
tic();IsMonoton(1:100000); toc()

Weiteres Beispiel:

// compile: cl /LD test.cpp user32.lib

#include <windows.h>

extern "C" __declspec( dllexport ) int ShowMessage(char *psMsg);

__declspec (dllexport) int ShowMessage(char *psMsg)
{
    MessageBox(NULL, psMsg, "UniPlot", MB_OK);
    return 0;
}

3.5. Wie führt man ein UniScript-Beispiel aus ?

Es gibt da mehrere Möglichkeiten:

Falls es sich um eine einzeilige Anweisung handelt, wie die folgende Zeile

MessageBox("Hallo");

kopieren Sie diese Zeile in das UniScript-Kommandofenster. Markieren Sie die Zeile dazu mit der Maus. Drücken Sie danach die rechte Maustaste und wählen Sie den Befehl kopieren.

Im UniPlot-Kommandofenster, das Sie über den Befehl Ansicht=>Kommando-Fenster erreichen, drücken Sie dann die Tastenkombination Shift-Einfg. Drücken Sie dann die Enter-Taste.

Falls es sich um mehrere Anweisungen handelt, wie im folgenden Beispiel:

x = linspace(1, 2*PI)
y = sin(x)
plot(x,y)

kopieren Sie die Zeilen nacheinander in das Kommandofenster und führen Sie die Zeilen aus.

Falls es sich um viele Anweisungen oder Funktionen handelt, kopieren Sie den Text in einen UniPlot-Programm-Editor. Um einen Editor zu erzeugen, wählen Sie Datei=>Neu und aus der folgenden Liste den Befehl Programm-Editor. Fügen Sie den Text aus der Zwischenablage mit der Tastenkombination Shift+Einf in den Editor ein und wählen danach den Befehl UniScript=>Speichern/Ausführen.

3.6. Kann man UniPlot/UniScript beim Aufruf Parameter übergeben?

Verwenden Sie den Schalter: /ini

Mit Hilfe dieses Schalters kann man UniPlot den Namen einer IC-Datei übergeben.

Eine Kommandozeile könnte z. B. so aussehen:

c:\Programme\uniplot\program\uniplot.exe /ini test.ic

Die Datei test.ic könnte z. B. so aussehen:

// Erstmal die normale Startup-Datei laden:
load(GetRootDirectory() + "startup/startup.ic");
// Hier kommen Ihre Anweisungen und Funktionen hin:
MessageBox("Dies ist ein Test");
x = linspace(1, 2*PI, 500);
y = sin(x);
plot(x, y);
MessageBox("Nun wird das Programm wieder beendet.");
// zum Schluß wird UniPlot wieder beendet.
AppQuit();

Mit der Funktion AppGetCommandLine können Sie auf die Argumente in der Kommandozeile zugreifen.

c:\Programme\uniplot\program\uniplot.exe /ini test.ic Argument1 Argument2

AppGetCommandLine liefert dann "/ini test.ic Argument1 Argument2". Diesen String können Sie dann mit der Funktion strtok zerlegen.

id-1874822