开发者

How to interface with an executable in C++

I have an executable that I need to run some tests on in C++ - and the tes开发者_JAVA技巧ting is going to take place on all of Windows, Linux and Mac OSes.

I was hoping for input on:

  • How would I interface with the previously built executable from my code? Is there some kind of command functionality that I can use? Also, since I think the commands change between OSes, I'd need some guidance in figuring out how I could structure for all three OSes.

EDIT - Interface = I need to be able to run the executable with a command line argument from my C++ code.

  • The executable when called from the commandline also ouputs some text onto a console - how would I be able to grab that ouput stream (I'd need to record those outputted values as part of my tests).

Feel free to ask me follow up questios.

Cheers!


If you use qt to develop your code, you'll find QProcess will allow you to spawn a command line program in a platform-agnostic way.

Essentially:

 QObject *parent;
 QString program = "yourcommandlineprogram";
 QStringList arguments;
 QProcess *myProcess = new QProcess(parent);
 myProcess->start(program, arguments);

You can then read from the process with various function calls such as readAllStandardOutput (), and write to the input of the process with QProcess::write(QString).

Alternatively, if you prefer Boost to Qt, Boost.Process will also let you launch processes. I confess I don't like the syntax as much...

boost::process::command_line cl("yourcommandlineprogram");
cl.argument("someargument");
boost::process::launcher l;
l.set_stdout_behavior(bp::redirect_stream);
l.set_merge_out_err(true);
l.set_work_directory(dir);
boost::process::child c = l.start(cl);

You can then work with your subprocess 'c' by using stream operators << and >> to read and write.


All those OSes support some form of "subprocess" calling technique, where your tester creates a new child process and executes the code under test there. You get to not only pass a command line, but also have the opportunity to attach pipes to the child process' standard input and output streams.

Unfortunately, there is no standard C++ API to create child processes. You'll have to find the appropriate API for each OS. For example, in Windows you could use the CreateProcess function: MSDN: Creating Processes (Windows).

See also Stackoverflow: How do you spawn another process in C?


As I understand, you want to:

  1. Spawn a new process with arguments not known at runtime.
  2. Retrieve the information printed to stdout by the new process.

Libraries such as QProcess can spawn processes, however, I would recommend doing it by hand for both Windows and MacOS/Linux as using QProcess for this case is probably overkill.

For MacOS/Linux, here's what I would do:

  1. Set up a pipe in the parent process. Set the read end of the pipe to a new file descriptor in the parent.
  2. fork.
  3. In newly created child process, set stdout (file descriptor #1) to the write end of the pipe.
  4. execvp in the newly created child process and pass the target executable along with what arguments you want to give it.
  5. From the parent process, wait for the child (optional).
  6. From the parent process, read from the file descriptor you indicated in Step 1.


First of all, is it possible that you simply need to want to make your original code reusable? In that case you can build it as library and link it in your new application.

If you really want to communicate with another executable then you can need start it as a subprocess of the main application. I would recommend the Process class of the Poco C++ libraries.


Looks like a job for popen(), available on Linux, Windows, and OS X


Sounds like you are only planning to do functional testing at the executable level. That is not enough. If you plane to do thorough testing, you should also write unit tests. For that there is some excellent frameworks. My prefered one (by far) for C++ is BOOST::Testing.

If you control source code there is also common tricks for functional testing beside launching exe from an external process : embed functional tests. You just add an option to your program that execute tests. This is cool because tests are embedded in code and autocheck can easily be launched in any execution environment.

That means that in the test environment, as you call your program with some test dedicated arguments, nothing keeps you from going the full way and redirect the content of stdout and even check the tests results from within the program. It will make the whole testing much easier than calling from an external launcher, then analysing the results from than launcher.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜