Matlab system function with a C executable - c

I have written a Matlab GUI for my C program. I thought about using MEX, but there are too many C files and C program requires a DLL to run.
So, instead I have the Matlab System function calling the executable with inputs, something like [status results] = system('executable "input 1" "input 2"'), which runs well, but I want real time output. results is just a percent output of how complete the program is, and I want to use this output for a GUI progress bar in Matlab.
The output does get stored into results, but only after the program is complete. Thus, making the progress bar pointless.
Is it possible to get the executable to send outputs one at a time to Matlab, and then have Matlab update the progress bar, and return to the executable?
Edit: I'm looking for a solution in Windows.

I only see two options, and neither fits directly with your current implementation approach.
The first, is to just use sockets to communicate between the two. Here's a pure matlab socket implementation, but under the hood it's using C sockets. It's been 10 years since I've done C/Java socket comms, but I recall that at the time there were some issues.
http://www.mathworks.com/matlabcentral/fileexchange/21131-tcpip-socket-communications-in-matlab
Another option is to have your executable be accessible via a C DLL from matlab, and call the DLL directly from matlab (i.e. have matlab control your app). This is the way I've been doing most such interactions lately, and it works very well.
http://www.mathworks.com/help/techdoc/ref/loadlibrary.html

I found a solution. Credit goes to Richard Alcock at Matlab Central
Specifically, for my solution:
cmd = {'executable.exe', 'input 1', 'input 2'};
processBuilder = java.lang.ProcessBuilder(cmd);
cmdProcess = processBuilder.start();
% Set up a reader to read the output from the command prompt
reader =
java.io.BufferedReader(...
java.io.InputStreamReader(...
cmdProcess.getInputStream() ...
) ...
);
% Loop until there is some output
nextLine = char( reader.readLine );
while isempty(nextLine)
nextLine = char( reader.readLine );
end
% Then loop until there is no more output
while ~isempty(nextLine);
fprintf('Output: %s\n', nextLine);
nextLine = char( reader.readLine );
end
% Get the exit value of the process
exitValue = cmdProcess.exitValue
Note: this code does not hold up the executable. The executable must finish before this code finishes, otherwise this code crashes when it gets ahead of the executable.

Related

CP/M get running program name

For a hobby project I'm porting the Standard C Library to the Digital Research CP/M.
Inside CRT0.S (this is the code that runs before your main() C function is called) I have no trouble parsing the tail of the command line arguments from the lower memory, but I'm unable to get the running program name i.e. if I type
memdump 0xfc00 100
I'd like to obtain memdump or memdump.com from CP/M in a nice way so that I can set my args to (pseudo code) correctly
argv[0] = "memdump.com";
argv[1] = "0xfc00";
argv[2] = "100";

Creating an initialization file in pari-gp

This question is definitely a stupid question. But, coming from C; I'm having trouble adding header files or "an initialization" file to my pari-gp code. This is to mean; I have a 1hr compile of code to make one vector; and I can use that vector once initialized; but I want to make a file of this vector such that I can access it once it's compiled once.
Here's the code without a header file; which takes about an hour to compile (given the series precision/numerical precision which are set to 100).
\p 100
\ps 100
Phi_Inv(w,l,{n=100}) =
{
my(out = 0);
for(i=0,n,
out = w*exp(out)/(exp(l*(n+1-i))+w)
);
out;
}
beta_init(n) = {
beta_taylor = vector(100,i,polcoef(Phi_Inv(w,l,n),i-1,w));
print(beta_taylor);
}
Rather than the brutal assignment of beta_taylor; and the caveman like print(beta_taylor), how can I write this to an initialization file I can package with the script. That is; an X mb file with all the coefficients neatly packed together. And if the file is lost, just run the code (which will take an hour) to write the initialization file again.
I mean, how would I properly do #include test.h where test.h is just a very long list of Taylor series values. So that I can just include this file, and write beta_taylor[i] for the i'th function. Such that it's as simple as including variables, like in C. I know I'm missing something simple and it's frustrating--making me feel stupid.
I'm mostly just asking about the syntax to go about and do this. I think I know how; but I imagine it's not the best way.
Any help or suggestions are greatly (And I really mean it, Greatly) appreciated.
To make a long story short; how do I save beta_taylor as a file we load when we initialize the program, and if the file is deleted we can save the program again by running the code for an hour?
Regards
So you want to serialize your vector of numbers to a file and read it back in later?
writebin() to the rescue. Something like
beta_init(n) = {
beta_taylor = vector(100,i,polcoef(Phi_Inv(w,l,n),i-1,w));
writebin("beta_taylor.dat", beta_taylor);
}
Run the function in one gp session, and then in another session, beta_taylor=read("beta_taylor.dat").
Compiling your code first with gp2c before running it to calculate the numbers will speed things up if you're not already doing that, btw. gp2c-run makes it easy by compiling a file and starting a new gp session with the resulting shared library already loaded. You might also look into if the parallel operations can be used here to speed up the initial computation; reading the documentation for parvector() I don't think it can be, though, because of that mysterious l variables used in beta_init() that I don't see you define anywhere, but you might be able to re-phrase your equation with hardcoded constants or something.
An initialization for Pari/GP, at program start:
(file gprc.txt in directory of gp.exe)
lines = 25
colors = "brightfg"
histfile = "gp_history.txt"
breakloop = 0
help = "# perl\\perl gphelp.pl -detex -ch 10 -cb 11 -cu 12"
prompt = "gp >"
prompt_cont="gpc>"
datadir = "u://paritty/syntax/_v11/"
path = "u://paritty/syntax/_v11/"
primelimit = 100 000 000
parisizemax = 1 000 000 000
read "__init.gp"
echo = 0
The file __init.gp contains my generally used functions; commands to read precomputed data-vectors can of course be included there. If no path is indicated it will be searched in the directory given in the path= statement.

Rebound: fatal error while opening a file

I am using a software called Rebound which is a type of N-body integrator that generates simulations according to a certain code I wrote. the software uses built in functions of its own which are based on C.
part of the code I wrote is when I'm telling the program to output certain data into separate text files every set period of time.
char array [1000000];
if (reb_output_check(r, 49.581410)){
sprintf(array, "output%d.txt", i);
i++;
reb_output_orbits(r, array ); //output the orbital elements
}
the reb_output_check function checks whenever the time is a multiple of 49.581410 years in simulation r to execute the rest.
everything is working out fine until the 252nd output where the simulation stops and this appears:
Fatal error! Exiting now. Can not open file
I've repeated the simulation more than once and I'm getting the same thing at the same time every time. I don't know why it's giving me this.
any help regarding the matter is much appreciated.

Calling C shared library function from LibreOffice Basic

I'm trying to call a C shared library function from LibreOffice Basic, but I always get "Basic Runtime Error. Not implemented" when it hits the Declare line. It's just for a fun thing but being unable to do it is bugging me.
The Declare statement looks like this:
Declare Function score_word Lib "libscrabblescore.so" (ByRef word As String, ByRef bonus As String) As Integer
The C function delaration looks like this:
int score_word(char* word, char* word_bonuses)
(Maybe ByRef word As String is not the right translation of char* word? I can't find documentation on how to use char* parameters to functions from LibreOffice Basic.)
I validated the shared library itself by calling it using Python's ctypes module:
>>> from ctypes import CDLL
>>> lib = CDLL("/usr/lib/libscrabblescore.so")
>>> lib.score_word("qi", "dw dlq")
42
>>>
(So I have the "Answer to the Ultimate Question of Life, the Universe, and Everything," just not for how to do this in LibreOffice Basic!)
I tried using the absolute path in the Declare statement as well, and it made no difference.
I found a Windows thread on the topic of calling DLL's where the asker said he needed to put the DLL in a specific location (the LibreOffice bin directory) so LibreOffice could access it. There is no LibreOffice bin directory per-se on Linux, and unfortunately there are 351 candidate directories I was able to identify on my machine (my path, and all folders with "libreoffice" in the name or under a folder with "libreoffice" in the name).
I tried a shotgun approach and put a symbolic link to the shared library in all 351 directories, but then Calc hangs on startup. So I removed those, started Calc, and put them all back in place and tried the function. If it was a location thing, you'd think that would work as LibreOffice Basic is supposed to load the library at the point of the Declare. Still no luck.
There was something that looked promising on oooforums but the site times out when I try to view the thread. (EDIT: I managed to view the thread this evening and it was Windows security problem. I turned off all macro security in my LibreOffice and still have the problem.)
So, has anybody ever successfully called a C shared library function from a LibreOffice Basic program that knows what I'm doing wrong? Thanks!
Jonathon Reinhart is correct; the "Declare" command for calling shared libraries is implemented on Windows but not on Linux. I was only able to verify this because of a reference to an OpenOffice bug report on the matter on a blog post.
My first attempt at a solution was to rewrite the function in LibreOffice Basic. It worked, but would take up to 3 seconds to return its results.
I considered giving up and leaving it like that, but it was too unpleasant to have a three second wait. I looked into how to implement a C++ function through UNO, which was overly complex for a fairly trivial task.
Finally what I did was to write a kludge that still gives "instant" results (around 0.025 seconds each function call).
I rewrote the DLL as a C++ console app that takes command line arguments and writes the result to a temp file. Then I replaced my LibreOffice Basic code with a function that calls the C++ console app in blocking mode using Shell and retrieves the results from the file. It's ugly, but it's not a multi-user thing and it works.
In case anyone stumbles across this issue themselves, here's the LibreOffice Basic code I used to do this--it's very simple.
option explicit
function scorewords(wordlist as string, bonuslist as string) as integer
dim cparams as string
dim fileno as integer
dim results_file as string
dim score as integer
if wordlist = "" then
scorewords = 0
exit function
end if
cparams = """" + wordlist + """" + " " + """" + bonuslist + """"
results_file = "/tmp/scrabblescore.dat"
Shell("/usr/bin/getscrabblescore", 6, cparams, true)
fileno = freefile
open results_file for input as fileno
input #fileno, score
close #fileno
kill results_file
scorewords = score
end function
Unless you are limited to Basic then it looks like your question already shows a good solution. Write something like this in Python UNO:
import ctypes
lib = ctypes.cdll.loadLibrary("/usr/lib/libscrabblescore.so")
result = lib.score_word("qi", "dw dlq")
oText.insertString(oTextCursor, result, 0)

Read a line of c code from file and execute in a c program

I have a C program which calculates f(x) for some x values (main.c). I need to get a line of c code from file and that code is my function to execute (function.dot). For example function.dot will contain:
pow((1-x), 0.333);
I need to read this file, get that function and execute in my code (main.c). How can I do that?
Basic steps would be:
Read the line from the file.
Generate a new source file which wraps the line of code inside appropriate code.
Invoke a compiler to compile that code into a shared object/dll.
Load the library.
Call the function in the library.
If the single line of code in the file could be any language, it would be far easier to use something like Lua that can be linked into your main executable.
I will provide some options:
Switch to another interpreted language including python, ruby, perl, ...
If you are working on small project, I recommend this option.
Implement your own interpreter in C.
Parse your input, analyze it, execute it. You might find open source implementations: one choice is slang
http://www.jedsoft.org/slang/doc/html/slang.html
Call C compiler and dynamically link it.
It depends on your operating system but system or exec functions help you to call your compiler to handle your input file. If you are using Linux, dlsym can open a shared-object compiled from your input file.
You might need to convert your input file into C program.
Very slow to compile but fastest to run.
You have several options I can think of:
1) Switch to any number of interpreted langauges (python, perl, etc.) which support this as an easy mechanism. (Example: in python
data = open("function.dot").read()
x = 5
eval(data) #note that this is unsafe if you can't trust data, and you might also need to play with environment
)
2) You could wrap the code in it's own c file... something like (but with more error checking etc... you probably don't want to do this)
void generate_c_program(char *line)
{
FILE *fp = fopen("myfile.c","wt");
fprintf(fp,"#include <math.h>\nint main(char *argv, int argc) {\n double x = atof(argv[1]); printf(\"%f\",(%s));}\n");",line); //this is also unsafe if you can't trust data
fclose(fp);
//now execute gcc myfile.c
//now execute a.out
//optionally cleanup by deleting a.out and myfile.c
}
3) Effectively write your own compiler / parser (which may be fairly easy IF you've done this before and the number of functions / operations you need to support is small or may be a much bigger deal and will rather not fit in this answer)... the extensible way would be to use LEX/YACC or similar)

Resources