Communicating between a ruby script and a running c++ program - c++

I have a c++ program which performs one function. It loads a large data-file into an array, receives an array of integers and performs a lookup in that array, returning a single integer. I am currently calling the program with each integer as an argument, like so:
$ ./myprogram 1 2 3 4 5 6 7
I also have a ruby script, and I would like this script to utilize the c++ program.
Currently, I am doing this like so.
Ruby Code:
arguments = "1 2 3 4 5 6 7"
an_integer = %x{ ./myprogram #{arguemnts} }
puts "The program returned #{an_integer}" #=> The program returned 2283
This is all working properly, but my problem is that each time ruby makes this call, the c++ program has to reload the data-file (which is over 100mb) - very slow, and very inefficient.
How can I rewrite my c++ program load the file only once, allowing me to make many lookups via a ruby script without reloading the file each time. Would using sockets be a sensible approach? Writing the c++ program as a ruby extension?
Obviously I am not an experienced c++ programmer, so thanks for your help.

A possible approach is to modify your C++ program so that it takes its input from the standard input stream (std::cin) instead of from the command line parameters, and returns its result through the standard ouput (std::cout) instead of as main's return value. Your Ruby script would then use popen to launch the C++ program.
Assuming the C++ program currently looks like:
// *pseudo* code
int main(int argc, char* argv[])
{
large_data_file = expensive_operation();
std::vector<int> input = as_ints(argc, argv);
int result = make_the_computation(large_data_file, input);
return result;
}
It would be transformed into something like:
// *pseudo* code
int main(int argc, char* argv[])
{
large_data_file = expensive_operation();
std::string input_line;
// Read a line from standard input
while(std:::getline(std::cin, input_line)){
std::vector<int> input = tokenize_as_ints(input_line);
int result = make_the_computation(large_data_file, input);
//Write result on standard output
std::cout << result << std::endl;
}
return 0;
}
And the Ruby script would look like
io = IO.popen("./myprogram", "rw")
while i_have_stuff_to_compute
arguments = get_arguments()
# Write arguments on the program's input stream
IO.puts(arguments)
# Read reply from the program's output stream
result = IO.readline().to_i();
end
io.close()

Well,
You could go about this a number of different ways.
1) A simple, potentially ugly way to do this is to have your c++ run and intermittently check for a file, have your ruby script produce said file containing your arguments. Your C++ program would then use the contained arguments returning it's result to a result file which you could wait on within your ruby script... This is obviously HACK TASTIC but it's uber simple to implement and would work.
2) Expose your c++ code as a c extension to ruby. This is not as hard as it's sounds especially if you use RICE and would provide significantly less hackie solution.
3) If your c++ can be exposed through a c header file then it's almost trivial to construct a bridge using FFI. Jeremy Hinegardner gave a good lecture on constructing FFI interfaces at rubyconf heres the screencast
4) D-Bus provides an application communication bus, you could alter your C++ app to take advantage of said event bus and pass messages from your ruby using ruby-dbus
There are of course a thousand other routes... Maybe one or the other of these could prove viable :)
Cheers!

Related

How to Run a C++ program inside a Rails 4 WebApp

I'm interested in implementing a program written in C++ inside a Ruby on Rails 4 App.
The C++ app runs in console and works by giving it a file, it processes it and then it outputs another file.
I found 'Ruby Inline', a gem that allegedly allows the use of foreign code:
https://rubygems.org/gems/RubyInline
gem 'RubyInline', '~> 3.12', '>= 3.12.4'
Inline allows you to write foreign code within your ruby code. It automatically determines if the code in question has changed and builds it only when necessary. The extensions are then automatically loaded into the class/module that defines it. You can even write extra builders that will allow you to write inlined code in any language. Use Inline::C as a template and look at Module#inline for the required API.
According to the documentation, it allows the use of C and C++ programs like this:
require 'inline'
class MyTest
inline(:C) do |builder|
builder.include '<iostream>'
builder.add_compile_flags '-x c++', '-lstdc++'
builder.c '
void hello(int i) {
while (i-- > 0) {
std::cout << "hello" << std::endl;
}
}'
end
end
t = MyTest.new()
t.hello(3)
The problem is that I'm not entirely sure how to implement it with a larger C++ program made out of multiple files, I'm not proficient in C++.
This seems like a gem to add the C++ code inside a ruby script and the C++ program is made out of multiple files and folders.
Will Ruby Inline work for what I want to do or is there a better option out there?
Is there a way to call the C++ app directly without putting it inside a ruby file?
The file to be given to the C++ app will be uploaded via the web interface, how can I feed it to the C++ program so it outputs the result?
Ruby supports the functionality to run native commands using the ` character. For example, we have a C++ program below, that takes two arguments, and then prints to standard output both of them, concatenated together. The course code for this program can be seen below:
#include <iostream>
int main(int argc, char ** argv){
std::cout << argv[1] << argv[2] << std::endl;
return 0;
}
While the C++ code, really only needs to be compiled a single time, and this step wouldn't likely be necessary, we can compile it from within ruby by doing the following: (You can replace g++ with the compiler of your choice.) We will set the variable success to true if the command successfully compiles, false otherwise.
pathToSource = "your/path/to/file.cpp"
outputBinaryFile = "your/desired/output/file.bin"
success = system("g++ #{pathToSource} -o #{outputBinaryFile}")
Now that we have compiled our code, we can execute it by running the following in ruby:
word1 = "Hello"
word2 = "World"
commandOutput = `./#{outputBinaryFile} '#{word1}' '#{word2}'`
Which will set commandOutput to: "HelloWorld\n"
You may need to change small things such as the compiler depending on the system that you are running, but this should function for you on *NIX systems.

How do I take in "standard input commands" and then know when to continue running the program?

I'm working on a traveling sales person program in C++. I'm very new to C++ and its so much different from Java that the simple things really get confusing.
How do I use standard input to accept commands from a file (apparently I don't open the file, my professor just uses it to feed in commands or something) and then use those commands to run my program accordingly?
An example would be
city a
city b
city c
city d
a c 1300
a d 1400
a b 900
d c 1500
So basically an unknown amount of information is going to be passed into my program and then my program needs to declare a specific number of cities and then attach travel costs between each of them as specified. I think I can do the latter part, but my problem is knowing how to take an unknown number of inputs and then attach those inputs to variables.
I guess in Java I would do something like this:
While(nextLine = true){
if (nextLine.contains ("city"){
String nextLine = nextLine;
...and so on
}
}
Start with waiting a filename by ifstream, then you can get inputs by char or line in which using a char pointer and determine it with text size i believe somethig like this
std::ifstream::pos_type filesize(const char* filename)
{
Now you buffered, go on for what you know from java and combine it. Besides, like Sam's sugesstion, u you should read

passing on inputs to an exe file using c++

lets say we have a cal.exe file (a simple addition calculator programmed programmed in c++).
lets say that the console output screen first displays enter the first number: and waits for the user to input an integer value. I am willing to create a c++ program that would "pass on" the required value to the running process (cal.exe) as an input (playing the role of a user). I would also like to have the output from the cal.exe file to be displayed and interpreted by my program.
I havent got the slightest idea how to proceed with this. Is there any open source library that would help me accomplish this? If there is, could you name a few?
I have just learned object oriented programming in c++ last year in my school and I am not used to these kind of stuff in programming; so please excuse me if this question is silly.
update:
lets consider 2 processes a.exe and b.exe running. could you tell me a possible way to program b.exe which provides a integer input to a.exe (a console process) as if it was from the user?
You can do this by accepting command line arguments.something like this
int main ( int argc, char *argv[] )
{
enter code here
return 0;
}
Where,
First argument to main function (argc) refers to the number of arguments being passed to the program at run-time.
Second (char *argv[] )refers to a string containing the arguments that are passed (char * is treated as String also ).
Argument names may vary as per the user specifications.
For details Refer:
http://www.cplusplus.com/articles/DEN36Up4/
And for nesting of programs you can use system("name of child program goes here") Function under stdlib.h.
For details Refer:
http://www.cplusplus.com/reference/cstdlib/system/

c++ software passing arguments method

I have a problem related to passing arguments to a C++ compiled executable. The program emulate the behaviour of a particular inference engine: the setup of the engine is load at runtime from an XML file, and then I want to call it from command line with different input values.
The characteristic of the input are:
Every time that I call the program, the input structure is different, because the system itself is different.
The input is a set of couple {name, value}, one for each part of the system.
I have to separate the configuration XML from the input.
I call the program from a PHP or Node.js server, since it return a result that I expose to the outside through an API.
Input value are obtained from an HTTP post request.
By now I have tried these solutions:
Pass it from the command line ex: "./mysoftware input1 value1 input2 value2 ...etc". A little unconfortable, since I have up to 200 input.
Create a file with all the couples name,value and then call the program that parse the file and then destroy at the end. This is a bottleneck of performance for my API, because at every call I have to create and destruct a file.
Does anyone know a better way to approach this problem?
3. Pass the values to the program via the standard input stream and read them from std::cin inside your C++ program.

How to run a C++ program in another C++ program?

I have a simple C++ program that takes in inputs and outputs some string. Like this:
$ ./game
$ what kind of game? type r for regular, s for special.
$ r
$ choose a number from 1 - 10
$ 1
$ no try again
$ 2
$ no try again
$ 5
$ yes you WIN!
Now I want to write a c++ program can runs this c++ program and plays the game automatically without user input and then outputs it to a file or standard output.
Running it would look like this:
./program game r > outputfile
game is the game program, r for playing regular style.
How should I do this? The main reason I need this program is that I want to do automatic testing for a much bigger program.
You could use std::system from <cstdlib>:
std::system("game r > outputfile");
The return value is ./program's, the sole argument must be of type char const *.
There is no standard way to run a program and feed it standard input, though. Judging by your command line, you're on some Unix variant where popen from <stdio.h> should work:
FILE *sub = popen("game r > outputfile", "w");
then write to sub with the stdio functions and read outputfile afterwards.
(But for simple testing, I'd recommend implementing the core logic of your program as a set of functions/classes that can be run by a custom main function in a loop; or pick your favorite scripting language to handle this kind of thing.)
I'd be more efficient to add a caller function to your main source and have it control looping, logging, and feeding input. It would also not require system calls or other magic to pull off. Being a game programmer, we have our games play themselves as much as possible to help with debugging, and almost always this is done via internal code, not through external scripting or system calls. It makes it easier to feed viable input as well.
This scenario cries out for a "script", IMHO.
Bash, Perl, Python - you name it.
SIMPLEST CASE:
Just write a bash script to call ./program game r > outputfile.
Or ./program game r < test_input.txt > test_output.txt
For more advanced scenarios, you might want to look at "expect".
You might also want to look at "STAF", which might be a great way to "automate your automated tests":
http://staf.sourceforge.net/current/STAFFAQ.htm