2010-02-18 77 views
4

我有一个执行一个函数的C++程序。它将大数据文件加载到数组中,接收一个整数数组并在该数组中执行查找,返回一个整数。目前我正在打电话,每个整数程序作为参数,就像这样:在ruby脚本和正在运行的C++程序之间进行通信

$ ./myprogram 1 2 3 4 5 6 7 

我也有一个红宝石脚本,我想这个脚本能利用C++程序。 目前,我正在这样做。

的Ruby代码:

arguments = "1 2 3 4 5 6 7" 
an_integer = %x{ ./myprogram #{arguemnts} } 
puts "The program returned #{an_integer}" #=> The program returned 2283 

这是所有工作正常,但我的问题是,每次红宝石使得这个调用,C++程序必须重新加载数据文件(超过100MB) - 很速度慢,而且效率很低。

如何重写我的C++程序只加载一次文件,这使我可以通过ruby脚本进行多次查找,而无需每次重新加载文件。使用套接字是一个明智的方法?把C++程序写成ruby扩展?

显然我不是一个有经验的C++程序员,所以非常感谢您的帮助。

回答

6

一种可能的方法是修改您的C++程序,以便它从标准输入流(std :: cin)而不是从命令行参数获取输入,并通过标准输出(std :: cout)而不是主要的返回值。你的Ruby脚本会使用popen来启动C++程序。

假设C++程序目前的样子:

// *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; 
} 

将它改造成类似:

// *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; 
} 

而且Ruby脚本会是什么样子

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() 
3

好,

你可以通过很多不同的方式来解决这个问题。

1)一个简单的,潜在的丑陋的方式做到这一点是让你的C++运行和间歇检查文件,有你的Ruby脚本产生上述文件,其中包含你的论点。然后你的C++程序将使用包含的参数将其结果返回给你可以在你的ruby脚本中等待的结果文件......这显然是HACK TASTIC,但它实现起来非常简单,并且可以工作。

2)将C++代码公开为ruby的c扩展。这不像听起来那么难,特别是如果你使用RICE并且会提供更少的hackie解决方案。 3)如果你的C++可以通过c头文件暴露出来,那么使用FFI构造一个桥几乎是微不足道的。杰里米Hinegardner给了一个很好的演讲上,在RubyConf的构建FFI接口继承人the screencast

4)D-Bus提供一种应用程序通信总线,你可以改变你的C++应用程序来获取所述事件总线的优势,并使用通过从红宝石消息ruby-dbus

当然有一千其他路线...也许这些或其他这些可以证明可行:)

干杯!

相关问题