3. Questions about UniScript¶
3.1. I have edited one of the UniScript Files. The next time I started UniPlot the changes were gone. Why ?¶
During startup of UniPlot loads a library that contains all standard UniScript
functions. The library has the name rs_sl.icl
and is located in the
\UniPlot\Program
directory. After you have changed and translated
(command UniScript=>Save/Execute) any standard UniScript function in the
script
directory you need to rebuild the library. To do so choose
Tools=>Create UniScript Library.
3.2. How can I create a simple dialog box?¶
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 ?¶
The UniScript function system returns immediately. The following function
waits until the process is finished. The function uses the system functions
CreateProcessA
, WaitForSingleObject
and CloseHandle
from the Windows
DLL kernel32.dll
:
def System(ssCommand)
{
RegisterFunction("kernel32.dll", "CreateProcessA", "int", "CreateProcessA", ..
["int", "char*", "int", "int", "int", "int", "int", "int", "int*", "int*"])
RegisterFunction("kernel32.dll", "WaitForSingleObject", "int", "WaitForSingleObject", ..
["int", "int"])
RegisterFunction("kernel32.dll", "CloseHandle", "int", "CloseHandle", "int")
start = zeros(17,1)
process_info = zeros(4,1)
if (!CreateProcessA(0, ssCommand, 0, 0, 1, 0x08000000|32, 0, 0, start, process_info)) {
return FALSE;
}
while (WaitForSingleObject(process_info[1], 100)) {
;
}
CloseHandle(process_info[1]);
CloseHandle(process_info[2]);
return TRUE;
}
3.4. How can I write a DLL and call one of the DLL functions from UniScript?¶
The following is a simple C function which checks if an array of numbers is sorted increasingly.
// 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;
}
If you use the Microsoft-C Compiler to create the DLL (Dynamic Link Library) you also need a Linker Definition File:
.. code-block:: none
LIBRARY monoton EXPORTS monoton @1
With the Microsoft-C Compiler you are now ready to create the DLL
monoton.dll
. With other compilers this could look a little bit different.
CL /LD monoton.c monoton.def
Note:
1.) If the file is a C++ file the functions must be declared as extern "C"
.
Example:
extern "C" int monoton(double *p, int n);
2.) Instead of a linker definition file (*.def
) the functions can be declared
as following:
extern "C" __declspec(dllexport) int monoton(double *p, int n);
Now we are ready to test the new function. First we need to register it with the
help of RegisterFunction. Some C-Compilers add an underscore to the
function name. In this case call RegisterFunction with the following
second parameter "_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));
}
// Example: Copy the following lines into the command window:
IsMonoton(1)
IsMonoton([1,2,3,8])
IsMonoton([1,2,3,2])
tic();IsMonoton(1:100000); toc()
Another example:
// 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. UniPlot online documentation contains UniScript example scripts. How can I run these scripts ?¶
If for example the script contains only a single line,
MessageBox("Hello");
copy the line into the UniScript command window. To do so select the text line you want to copy. Click the right mouse key and choose copy.
In the UniPlot command window, which you can open by clicking the Command button, choose the hot key Shift+Ins and type ENTER to execute the command.
If the UniScript example consists of multiple commands like the following example
x = linspace(1, 2*PI)
y = sin(x)
plot(x,y)
copy the text into a UniPlot editor. To create a new editor window, choose File=>New and select the Program Editor item.
Press the Shift+Ins key to insert the text from the clipboard. To run the script choose UniScript=>Save/Execute and in the message box that appears, click the Yes button to save the file to your hard drive.
3.6. Can I start UniPlot with command-line arguments?¶
Use the command line switch: /ini
With this key you can pass an IC file name to UniPlot during startup.
A command line could look like the following:
c:\Program Files\UniPlot\program\uniplot.exe /ini test.ic
The file test.ic
could look like this:
// First start the standard UniPlot startup file (important!):
load(GetRootDirectory() + "startup/startup.ic");
// Now you can do what ever you like, example:
MessageBox("This is a test");
x = linspace(1, 2*PI, 500);
y = sin(x);
plot(x, y);
MessageBox("Now UniPlot will exit.");
AppQuit();
id-1874822