Reputation: 774
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?
Upvotes: 2
Views: 1372
Reputation: 1473
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.
Upvotes: 2