【问题标题】:How do I handle ruby arrays in ruby ffi gem?如何处理 ruby​​ ffi gem 中的 ruby​​ 数组?
【发布时间】:2015-04-01 11:15:23
【问题描述】:

我想使用 ruby​​ ffi gem 来调用一个 c 函数,该函数有一个数组作为输入变量,输出是一个数组。也就是c函数长这样:

double *my_function(double array[], int size)

我已将 ruby​​ 绑定创建为:

module MyModule
  extend FFI::Library
  ffi_lib 'c'
  ffi_lib 'my_c_lib'
  attach_function :my_function, [:pointer, int], :pointer

我想用 ruby​​ 代码进行调用,例如:

result_array = MyModule.my_function([4, 6, 4], 3)

我该怎么做?

【问题讨论】:

    标签: c ruby ffi


    【解决方案1】:

    假设这是您希望在 ruby​​ 脚本中使用的库,命名为 my_c_lib.c

    #include <stdlib.h>
    
    double *my_function(double array[], int size)
    {
      int i = 0;
      double *new_array = malloc(sizeof(double) * size);
      for (i = 0; i < size; i++) {
        new_array[i] = array[i] * 2;
      }
    
      return new_array;
    }
    

    你可以这样编译:

    $ gcc -Wall -c my_c_lib.c -o my_c_lib.o
    $ gcc -shared -o my_c_lib.so my_c_lib.o
    

    现在,可以在您的 ruby​​ 代码中使用它了 (my_c_lib.rb):

    require 'ffi'
    
    module MyModule
      extend FFI::Library
    
      # Assuming the library files are in the same directory as this script
      ffi_lib "./my_c_lib.so"
    
      attach_function :my_function, [:pointer, :int], :pointer
    end
    
    array = [4, 6, 4]
    size = array.size
    offset = 0
    
    # Create the pointer to the array
    pointer = FFI::MemoryPointer.new :double, size
    
    # Fill the memory location with your data
    pointer.put_array_of_double offset, array
    
    # Call the function ... it returns an FFI::Pointer
    result_pointer = MyModule.my_function(pointer, size)
    
    # Get the array and put it in `result_array` for use
    result_array = result_pointer.read_array_of_double(size)
    
    # Print it out!
    p result_array
    

    这是运行脚本的结果:

    $ ruby my_c_lib.rb
    [8.0, 12.0, 8.0]
    

    关于内存管理的注释...来自文档https://github.com/ffi/ffi/wiki/Pointers

    FFI::MemoryPointer 类使用自动垃圾收集作为甜味剂分配本机内存。当 MemoryPointer 超出范围时,内存将作为垃圾收集过程的一部分被释放。

    因此您不必直接致电pointer.free。另外,为了检查您是否必须手动释放 result_pointer,我在打印提取数组后调用了 result_pointer.free 并收到此警告

    warning: calling free on non allocated pointer #<FFI::Pointer address=0x007fd32b611ec0>
    

    看来您也不必手动释放result_pointer

    【讨论】:

      猜你喜欢
      • 2013-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多