Passing information between two seperate programs - c++

I want to pass a value of an input variable in my program lets say#1 to another program #2 and i want #2 to print the data it got to screen, both are needed to be written in c++. The this will be on Linux.

Depending on the platform there are a number of options available. What you are trying to do is typically called inter-process communication (IPC).
Some options include:
Sockets
Pipes
Queues
Shared Memory
What is easiest is probably dependent on the platform youa are using.

As always, there is a Boost library for that (God, I like Boost).

Nic has covered all the 4 that I wanted to mention (on the same machine):
Sockets
Pipes
Queues
Shared Memory
If writing system calls is troublesome for you, you may want to use the following libraries:
Boost http://www.boost.org/
Poco http://pocoproject.org/blog/
Nokia Qt http://qt.nokia.com/
Something you can read from Qt portable IPC: only QSharedMemory?

If effeciency is not prime concern then use normal file i/o.
else go for IPC to do so.
As far as Windows is concern you have following options :
Clipboard ,
COM ,
Data Copy ,
DDE ,
File Mapping ,
Mailslots ,
Pipes ,
RPC ,
Windows Sockets
For Linux , use can use Name Pipes(efficient) or sockets.

If you're on Windows, you can use Microsoft Message Queueing. This is an example of queue mentioned previously.

If the data to be passed is just a variable, then one of the option is to set it as Environment Variable [ Var1 ] by program #1 and access it, in Program #2 [ if both are running on same env/machine ]. Guess this will be the easiest one, instead of making it complex, by using IPC/socket etc.

I think most of the answers have address the common IPC mechanisms. I'd just like to add that I would probably go for sockets because it's fairly most standard across several platforms. I decided to go for that when I needed to implement IPC that worked both on Symbian Series 60 and Windows Mobile.
The paradigm is straightforward and apart from a few platform glitches, the model worked the same for both platforms. I would also suggest using Protocol Buffers to format the data you send through. Google uses this a lot in its infrastructure. http://code.google.com/p/protobuf/

DBUS
QtDbus
DBus-mm

In response to your comment to Roopesh Majeti's answer, here's a very simple example using environment variables:
First program:
// p1.cpp - set the variable
#include <cstdlib>
using namespace std;;
int main() {
_putenv( "MYVAR=foobar" );
system( "p2.exe" );
}
Second program:
// p2.cpp - read the variable
#include <cstdlib>
#include <iostream>
using namespace std;;
int main() {
char * p = getenv( "MYVAR" );
if ( p == 0 ) {
cout << "Not set" << endl;
}
else {
cout << "Value: " << p << endl;
}
}
Note:
there is no standard way of setting an environment variable
you will need to construct the name=value string from the variable contents

For a very dirt and completely nonprofessional solution you can do it like me.
Save the variable in to a file and then read it (in an infinite loop every x time) with the other program.
fsexample.open("F:/etc etc ...");
fsexample >> data1 >> data2; // etc etc
and on the other side
fsexample.open("F:/etc etc ...");
fsexample << data1 << data2; // etc etc
The trick is that F is a virtual drive created with ramdisk so it is fast
and heavy-duty proof.
You could have problem of simultaneous access but you can check it with
if (!fsexample.is_open()) {
fsexample_error = 1;
}
and retry on failure.

Related

Simplistic way to send data to another process (win)?

Suppose you are developing two application for the windows platform (A and B).
The platform/system is Windows (Windows 10 if that matters)
How can you send some piece of information to B from A if you are only allowed to work at the c++ language level (that is: including the standard libraries and STL) ? This rules out any third party libraries.
I'm trying to avoid the system API as it usually involves a healthy amount of c-like programming (and therefore is not suited for my purpose).
In this particular scenario both processes are running continuously and the sending happens due to some outside event (if it matters) - so some kind of sync is probably needed.
Possible solutions under consideration:
Using files, via std::ofstream and std::ifstream could be a possible solution (albeit a crude one) ? - but how can sync'ing be achieved then ?
Even redirecting STDOUT to STDIN could be fine - especially if there is some simple way to set this up (eg. one-liner on command line to start - powershell could be a possibility if needed)
A solution involving transfer via a datafile (this uses std::filesystem::rename as a way of sync'ing or you could say avoid it):
a.exe (writer)
#include <filesystem>
auto tmpfile = std::filesystem::temp_directory_path() / "some_uuid.txt";
auto datafile = std::filesystem::temp_directory_path() / "data.txt";
std::ofstream(tmpfile) << "hello" << std::endl;
std::filesystem::rename(tmpfile, datafile);
b.exe (reader)
auto datafile = std::filesystem::temp_directory_path() / "data.txt";
while (!std::filesystem::exists(datafile)) {
;//we have nothing else to do ?
}
std::ifstream input(data);
//read input etc.

C++ ifstream from linux to arduino

original code
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
ofstream arduino_output("/dev/ttyACM0");
ifstream arduino_input("/dev/ttyACM0");
int value;
string txt;
while(cin >> value){
arduino_output << value << endl;
arduino_input >> txt;//I never recieve the "OK" (Which I should get)
cout << txt;
}
arduino_input.close();
arduino_output.close();
return(0);
}
Here is the problem:
cin >> value;
arduino_output << value << endl;
arduino_input >> txt;//I never recieve the "OK" (Which I should get)
cout << txt;
but if I do this instead it works:
cin >> value;
arduino_output << value << endl;
for(int i=0;i<10000;++i)
for(int j=0;j<10000;++j){ //Waste a lot of time
++value;
--value;
}
arduino_input >> txt; //I always recieve the "OK"
cout << txt; //I can see the "OK"
So how do I make my fast computer able to read the slow output from the arduino? (Without using for-loops to waste time)
Here it says some things about callback http://www.cplusplus.com/reference/ios/ios_base/register_callback/ but I could never get it to work. It says it supports 3 events, and none of them are: "If input buffer is not empty, call this function".
Because the ultimate solution would be a callback function for whenever the input buffer is not empty.
An acceptable solution would be a c++ equivalent version of the arduino version "Serial.available()".
Another acceptable solution would be anything that forces me to not rely on two for-loops. 3 for-loops is not acceptable if that's what you're thinking.
EDIT1: Showed the original code
EDIT2: I am using linux(lubuntu)
EDIT3: Someone got confused where the code was written. Strange.
If your arduino board is connected -e.g. by some cable- to a Linux laptop and your C++
program is on the Linux side (so not running on the Arduino microcontroller, which you did program in free-standing C), you'll better use directly syscalls(2) and low-level IO (not C++ ifstream which adds some buffering) such as open(2) & read(2) & write(2) & close(2).
Read Advanced Linux Programming. Consider using termios(3) to perhaps set your tty (demystified here) in raw mode. Use poll(2) to multiplex (and wait for) input (or ability to output), e.g. like Serial.available() does inside the Arduino.
Some event loop libraries (e.g. libevent or libev) provide callbacks, but you can make your own event loop around poll.
To make some delay, use perhaps usleep(3) (but very probably, you need to poll instead).
PS. If your Linux application is a graphical one using some GUI toolkit like Qt or GTK, you should use the event loop provided by that toolkit (that loop is calling poll or select, etc...). BTW, your question is not really Arduino related, but serial port related (any other device plugged on the same serial port would give the same issues).
Your problem is weird. In general, the problem is that the slower party can't read what the faster party sends. So, it seems you have a more fundamental problem here.
If arduino_output is a representation of a serial port (UART), I suggest to use a platform specific way of accessing it. On Windows, there are UART functions, and on Linux there's termios (probably on most other POSIX-like, too). This will give you a way to control the parameters of communication, and get information and/or notification about events (including parity/framing errors).

Transferring data between executables

I have two executables written in C++ on Windows. I generate some data in one, and want to call the other executable to process this data. I could write the data out to a file then read it in the other executable, but that seems rather expensive in terms of disk I/O. What is a better way of doing this? It seems like a simple enough question but google just isn't helping!
Let's say the data is around 100MB, and is generated in its entirety before needing to be sent (i.e. no streaming is needed).
Answers that work when mixing 32 bit and 64 bit processes gain bonus points.
If your processes can easily write to and read from file, just go ahead. Create the file with CreateFile and mark it as temporary & shareable. Windows uses this hint to delay physical writes, but all file semantics are still obeyed. Since your file is only 100 MB and actively in use, Windows is almost certainly able to keep its contents fully in RAM.
You can use Boost.MPI. It is from Boost, which has high quality standard, and the code sample seems pretty explicit:
http://www.boost.org/doc/libs/1_53_0/doc/html/mpi/tutorial.html#mpi.point_to_point
// The following program uses two MPI processes to write "Hello, world!"
// to the screen (hello_world.cpp):
int main(int argc, char* argv[])
{
mpi::environment env(argc, argv);
mpi::communicator world;
if (world.rank() == 0) {
world.send(1, 0, std::string("Hello"));
std::string msg;
world.recv(1, 1, msg);
std::cout << msg << "!" << std::endl;
} else {
std::string msg;
world.recv(0, 0, msg);
std::cout << msg << ", ";
std::cout.flush();
world.send(0, 1, std::string("world"));
}
return 0;
}
Assuming you only want to go "one direction" (that is, you don't need to get data BACK from the child process), you could use _popen(). You write your data to the pipe and the child process reads the data from stdin.
If you need bidirectional flow of data, then you will need to use two pipes, one as input and one as output, and you will need to set up a scheme for how the child process connects to those pipes [you can still set up the stdin/stdout to be the data path, but you could also use a pair of named pipes].
A third option is a shared memory region. I've never done this in Windows, but the principle is pretty much the same as what I've used in Linux [and many years back in OS/2]:
1. Create a memory region with a given name in your parent process.
2. The child process opens the same memory region.
3. Data is stored by parent process and read by child process.
4. If necessary, semaphores or similar can be used to signal completion/results ready/etc.

Boost: how to create a thread so that you can control all of its standard output, standard errors?

I create a win32 console app in C++. I use some API (not mine, and I can not modify its sources). It Is written so that it writes some of its info onto console screen not asking... each time I call it (48 times per second) So I want to put it into some thread and limit its output capabilities, but I need to get notified when that thread will try to output some message which is important for me. I have message text in standard string. How to do such thing in C++ using boost?
Here's a crazy idea:
If the lib is using cout/cerr, you could replace the streambuf of these global variables with an implementation of your own. It would, on flush/data, check some thread-local variable to see if the data came from the thread that calls the library, then route it somewhere else (i.e. into a std::string/std::ostringstream) instead of to the regular cout/cerr streambufs. (Which you should keep around.)
If it's using c's stdout/stderr, I think it'd be harder to do properly, but it might be doable still. You'd need to create some pipes and route stuff back and forth. More of a C/unixy question then, which I don't know that much about... yet. :)
Hope it helps.
That feature does not exist in Boost. You can, however, use _dup2 to replace the standard out descriptor:
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <io.h>
#include <iostream>
#include <windows.h>
int main()
{
HANDLE h = CreateFile(TEXT("test.txt"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (0 == SetStdHandle(STD_OUTPUT_HANDLE, h)) {
std::fprintf(stderr, "`SetStdHandle` failed with error %d\n", (int)GetLastError());
return EXIT_FAILURE;
}
int h_desc = _open_osfhandle((long)h, 0);
_dup2(h_desc, STDOUT_FILENO);
std::printf("test\r\n"); // This actually writes to `h`.
std::fflush(stdout);
std::cout << "another test" << std::endl; // Also writes to `h`
CloseHandle(h);
return EXIT_SUCCESS;
}
Essentially what this trick does is allow you to redirect all writes to stdout, std::cout, and GetStdHandle(STD_OUTPUT_HANDLE) to a writable handle of your choosing (h). Of course, you can use CreatePipe to create the writable handle (h) and read from the readable end in another thread.
EDIT: If you are looking for a cross-platform solution, note that this trick is even easier on POSIX-compatible systems because dup2 is a standard function in unistd.h and "writable handles" are already descriptors.
I cannot think of a way to achieve in Boost what you want, as the problem is described.
However, this API behaviour is very perplexing. Spitting out reams of output to the console is a bit antisocial. Are you using a Debug build of the API library? Are you sure there's no way to configure the API such that it outputs this data to a different stream, so that you can filter it without capturing the entire standard output? Is there a way to reduce the amount of output, so that you only see the important events you care about?
If you really need to capture standard output and act on certain strings (events) of interest, then Win32 provides ways to do this, but I'd really take a hard look at whether this output can be modified to meet your needs before resorting to that.

How to easily pass a very long string to a worker process under Windows?

My native C++ Win32 program spawns a worker process and needs to pass a huge configuration string to it. Currently it just passes the string as a command line to CreateProcess(). The problem is the string is getting longer and now it doesn't fit into the 32K characters limitation imposed by Windows.
Of course I could do something like complicating the worker process start - I use the RPC server in it anyway and I could introduce an RPC request for passing the configuration string, but this will require a lot of changes and make the solution not so reliable. Saving the data into a file for passing is also not very elegant - the file could be left on the filesystem and become garbage.
What other simple ways are there for passing long strings to a worker process started by my program on Windows?
One possible strategy is to create a named Pipe and pass the handle ( or pipe name) to the other process. Then use normal Read\Write operations on Pipe to extract the data.
There are several good answers already, but the easiest way is to save it in a file, and pass the filename in the command line.
As well as being simple, an advantage of this approach is that the apps will be very loosely coupled (you'll potentially be able to use the child application stand-alone in other ways, rather than always having to launch it from a program that knows how to pipe data into it via a specialised interface)
If you want to be sure that the file is cleaned up after processing, mark it for deletion on the next reboot. THen if anybody forgets to clean it up, the OS will deal with it for you on the next reboot.
I would prefer Boost's message queue. It's extremely simple yet sophisticated. Here's example:
#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/shared_ptr.hpp>
using namespace boost::interprocess;
// ------------------------------------------------------------------------------
// Your worker:
// ------------------------------------------------------------------------------
try {
message_queue::remove("NAME_OF_YOUR_QUEUE");
boost::shared_ptr<message_queue> mq(new message_queue(create_only, "NAME_OF_YOUR_QUEUE", 65535, 32));
char message[1024];
std::size_t size_received;
unsigned int priority;
if (mq->timed_receive(&message, sizeof(message), size_received, priority, boost::posix_time::ptime(boost::posix_time::second_clock::universal_time()) + boost::posix_time::seconds(1))) {
std::string s(message); // s now contains the message.
}
} catch (std::exception &) {
// ...
}
// ------------------------------------------------------------------------------
// And the sender:
// ------------------------------------------------------------------------------
try {
boost::shared_ptr<message_queue> mq(new message_queue(create_only, "NAME_OF_YOUR_QUEUE", 1024, 1024));
std::stringstream message;
message << "the very very very long message you wish to send over";
while (!mq.try_send(message.str().c_str(), message.str().length(), 0))
::Sleep(33);
} catch (std::exception &) {
// ...
}
Use shared memory. Pass to a worker process name of shared memory object. Another solution is to use WM_COPYDATA message.
How about reading it from stdin :) It seems to work for the Unix folks.
Guaranteed a lot easier than passing pipe names/handles around!
Here is some official code from MSDN for creating child processes with I/O pipes.
Is it a possibility to set up a named shared memory segment?
http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx
You could use an inheritable handle to a section object. In your parent process create a section object (CreateFileMapping) and specify that its handle is to be inherited by the child process; then pass the handle value to the child process on the command line. The child process can then open the section object (OpenFileMapping). Though I would prefer a named section object as the semantics of using it are easier to understand.