Author |
Topic: Passing info between programs (Read 2159 times) |
|
Alincon
Full Member
member is offline
Posts: 147
|
|
Passing info between programs
« Thread started on: Feb 13th, 2015, 02:41am » |
|
I have been using the hidden text editor method to pass data between running programs, but it seems so crude. Is there a better, cleaner method in LBB? (or in LB4, for that matter)
r.m.
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Passing info between programs
« Reply #1 on: Feb 13th, 2015, 08:16am » |
|
on Feb 13th, 2015, 02:41am, Alincon wrote:I have been using the hidden text editor method to pass data between running programs, but it seems so crude. Is there a better, cleaner method in LBB? |
|
Several methods of inter-process communication (IPC) are available in Windows:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365574.aspx
Most of those can be used from LBB, with more or less difficulty. To give more detailed advice I would need to know the kind of data you want to pass, how quickly, whether it's in only one direction or bidirectional etc.
Richard.
|
|
Logged
|
|
|
|
SarmedNafi
Junior Member
member is offline
Posts: 93
|
|
Re: Passing info between programs
« Reply #2 on: Feb 13th, 2015, 10:17am » |
|
Wonderful Richard, For me: Quick in one direction.
Regards, Sarmed
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Passing info between programs
« Reply #3 on: Feb 13th, 2015, 11:48am » |
|
on Feb 13th, 2015, 10:17am, SarmedNafi wrote: The simplest method of unidirectional communication in LBB is to use a shared random-access file. The sending end opens the file for OUTPUT and the receiving end opens the file for INPUT. You should ideally store the file in the temp folder (use the 'GetTempPath' API to find this).
This is straightforward if you simply need to communicate a state: to update the state the sending end does a PUT, and the receiving end periodically tests it by doing a GET, probably in a timer subroutine. Here is a trivial example:
Compile this to filerecv.exe: Code: ' receiving end
tempfile$ = space$(260)
calldll #kernel32, "GetTempPathA", 260 as long, tempfile$ as ptr, ret as long
tempfile$ = left$(tempfile$, ret) + "LBBpipe.tmp"
open tempfile$ for input as #shared len = 20
field #shared, 20 as state$
timer 100, [test]
wait
[test]
get #shared, 1
print state$
wait And then run this in the same folder: Code: ' sending end
tempfile$ = space$(260)
calldll #kernel32, "GetTempPathA", 260 as long, tempfile$ as ptr, ret as long
tempfile$ = left$(tempfile$, ret) + "LBBpipe.tmp"
open tempfile$ for output as #shared len = 20
field #shared, 20 as state$
run "filerecv.exe"
timer 100, [send]
wait
[send]
state$ = date$("dd/mm/yyyy") + " " + time$()
put #shared,1
wait If you are sending a data stream rather than a state then this simple approach won't suffice and you need to think about issues of synchronisation and what happens if the 'sending' program outputs data more quickly than the 'receiving' program can accept it. This is a fundamental issue with unidirectional communication because the receiving end cannot say 'slow down'!
Richard.
|
|
Logged
|
|
|
|
Alincon
Full Member
member is offline
Posts: 147
|
|
Re: Passing info between programs
« Reply #4 on: Feb 13th, 2015, 4:09pm » |
|
I was thinking more of calling a program that does a common task and sends back the result. I have one that is called from programs that need standard state abbreviations. It presents a list box of State names and returns the corresponding abbreviation for the chosen state. I have another called program that verifies login and password. The calling program sends a name, the called program requests log in and password, and returns pass/fail. In the second case using the clipboard might compromise security. Using a common file might require timing to ensure the called program has finished before the calling program tries to use the requested data.
r.m.
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Passing info between programs
« Reply #5 on: Feb 13th, 2015, 5:27pm » |
|
on Feb 13th, 2015, 4:09pm, Alincon wrote:I was thinking more of calling a program that does a common task and sends back the result. |
|
I would have thought the 'standard' way of doing that (in general, unrelated to LB/LBB) is to use files. The vast majority of data processing and conversion programs I use take their input from one file and send their output to another file.
Apart from being such a commonplace method, using files for input and output may make it easier to debug because you can examine the files afterwards. I can't see any benefit in 'reinventing the wheel'.
Richard.
|
|
Logged
|
|
|
|
Phineas Freak
New Member
member is offline
Gender:
Posts: 18
|
|
Re: Passing info between programs
« Reply #6 on: Feb 14th, 2015, 08:26am » |
|
Take a look at the Memory Mapped Files demo from LBPE. You can probably transfer any kind of data between two or more program instances and without writting to the hard drive.
Note: I compliled it under linux. It runs but you cannot run a second instance and when you try to change the data on the first instance it complains about a "type mismatch". Commenting this line:
Code:g.caption$ = "Local string = " + str$(Shared.strVar.struct)
allows the first instance to change the data but i had no luck running a second instance to fully test it :-[ .
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Passing info between programs
« Reply #7 on: Feb 14th, 2015, 10:14am » |
|
on Feb 14th, 2015, 08:26am, PreciseTiming wrote:Take a look at the Memory Mapped Files demo from LBPE. |
|
Memory-mapped files (more accurately called 'shared memory' in this context) have the issue that I mentioned before: they are ideal for transferring a state but problematical for transferring a data stream. At least the communication is bi-directional so it would be possible to devise some kind of handshaking protocol.
Incidentally I think the code at LBPE is over-complicated. Whenever I've used shared memory (in BBC BASIC, I've never tried it in Liberty BASIC) I've not found it necessary to use the map-copy-unmap sequence for each transaction as recommended there. Leaving the structure mapped for the entire duration of the program has always worked for me:
http://bb4w.wikispaces.com/Sharing+a+structure+between+processes
Richard.
|
|
Logged
|
|
|
|
Alincon
Full Member
member is offline
Posts: 147
|
|
Re: Passing info between programs
« Reply #8 on: Feb 21st, 2015, 11:45pm » |
|
I have succeeded in passing information between programs by using a small file. My small file is sequential, not random, but it works.
I had concerns about this quote from the LB4 help file:
"Execution of an external program does not cause the calling Liberty BASIC program to cease executing."
But, at least in my case, it appears that the calling program does wait for the called .tkn program to finish.
r.m.
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Passing info between programs
« Reply #9 on: Feb 22nd, 2015, 07:04am » |
|
on Feb 21st, 2015, 11:45pm, Alincon wrote:But, at least in my case, it appears that the calling program does wait for the called .tkn program to finish. |
|
Sounds very risky to me. The RUN statement definitely doesn't wait; on a single-core CPU it may be a few milliseconds before it returns but you can't rely on it.
You say '.TKN'; was this using LB4 or LBB? In LBB you would need to use the WAIT qualifier to the RUN command.
Richard.
|
|
|
|
Alincon
Full Member
member is offline
Posts: 147
|
|
Re: Passing info between programs
« Reply #10 on: Feb 22nd, 2015, 12:31pm » |
|
Here's my code:
Code:
run "c:\libbas\_mylibbas\personnel\lookupNames.tkn ";"*.sal"
open "C:\libbas\_mylibbas\personnel\fileNamePass.txt" for input as #pnt
input #pnt, fileName$
close #pnt
The calling program passes a file type (via command line), and, presto! the file name is immediately available in the common file.
The called program fills an array for a list box and when the user makes a selection, passes back a file name.
Why would this be risky?
BTW: Is there any advantage in using a random file?
r.m.
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Passing info between programs
« Reply #11 on: Feb 22nd, 2015, 1:08pm » |
|
on Feb 22nd, 2015, 12:31pm, Alincon wrote: It's risky because if the file fileNamePass.txt is being created by the program lookupNames.tkn there's no reason at all to expect the file to have already been created when the RUN command returns.
The RUN command simply 'launches' the external program; then both that program and yours run concurrently. The degree of concurrency is of course dependent on your PC's architecture: if you have two or more CPU cores the programs may well be running literally simultaneously. If you have only one core they will be time-shared by Windows, but that is out of your control. Either way, the file may be created some time after the RUN command has returned.
But anyway this is evidently not LBB code ('RUN lookupNames.tkn' cannot work in LBB, unless you've associated the TKN extension with run404.exe), so you may want to raise the issue on one of the Liberty BASIC support forums.
Incidentally the ' ";" ' in your command string achieves nothing; you might as well (and more simply) use:
Code: run "c:\libbas\_mylibbas\personnel\lookupNames.tkn *.sal" Richard.
|
|
Logged
|
|
|
|
Alincon
Full Member
member is offline
Posts: 147
|
|
Re: Passing info between programs
« Reply #12 on: Feb 23rd, 2015, 5:55pm » |
|
Chris Iverson (on the LB msg board) says my code works for .tkn, but it won't work for .exe. That makes sense to me.
r.m.
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Passing info between programs
« Reply #13 on: Feb 23rd, 2015, 6:43pm » |
|
on Feb 23rd, 2015, 5:55pm, Alincon wrote:Chris Iverson (on the LB msg board) says my code works for .tkn, but it won't work for .exe. |
|
He seems to think that a TKN is run not as an 'external' program at all, but using the same runtime engine as the calling program. That may be true but AFAIK it's a completely undocumented feature. I wouldn't want to rely on it.
Certainly, LBB doesn't have a comparable capability (it could do in principle, but as it's so easy to compile a sub-program to a compact EXE you might just as well run it as a 'proper' external program). I could easily add a wait option to LBB's RUN command if that would be helpful*.
One thing I don't understand is why you're calling a sub-program at all. If it's also written in Liberty BASIC, why isn't it just implemented as a subroutine (in LBB it could be an 'included' library subroutine)?
*Edit: I've decided that I will add a wait option to the RUN statement in the next release of LBB. This will be mutually exclusive with the other modes (so you won't be able to wait and hide).
Richard.
|
|
|
|
Alincon
Full Member
member is offline
Posts: 147
|
|
Re: Passing info between programs
« Reply #14 on: Feb 24th, 2015, 12:01am » |
|
As to 'including', instead of 'calling', I guess I'm still thinking in LB4 terms; I chose calling because more than one program calls the routine
Thanks for offering to add a wait option to the run command, but if I'm the only one requesting it...
r.m.
|
|
Logged
|
|
|
|
|