简体   繁体   English

如何处理ruby ffi gem中的ruby数组?

[英]How do I handle ruby arrays in ruby ffi gem?

I want to use the ruby ffi gem to call ac function which has an array as an input variable and the output is an array. 我想使用ruby ffi gem来调用ac函数,它有一个数组作为输入变量,输出是一个数组。 That is, the c function looks like: 也就是说,c函数看起来像:

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

I have created the ruby binding as: 我创建了ruby绑定:

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

I will like to make a call in ruby code like: 我想用ruby代码打电话,如:

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

How do I go about this? 我该怎么做?

Let's say that this is the library you wish to use in your ruby script, call it my_c_lib.c : 假设这是您希望在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;
}

You can compile it like so: 您可以像这样编译它:

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

Now, it's ready to use in in your ruby code ( my_c_lib.rb ): 现在,它已准备好在你的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

And here is the result of running the script: 这是运行脚本的结果:

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

A note on memory management...from the docs https://github.com/ffi/ffi/wiki/Pointers : 关于内存管理的说明......来自文档https://github.com/ffi/ffi/wiki/Pointers

The FFI::MemoryPointer class allocates native memory with automatic garbage collection as a sweetener. FFI :: MemoryPointer类将自动垃圾收集的本机内存分配为甜味剂。 When a MemoryPointer goes out of scope, the memory is freed up as part of the garbage collection process. 当MemoryPointer超出范围时,内存将作为垃圾收集过程的一部分释放。

So you shouldn't have to call pointer.free directly. 所以你不应该直接调用pointer.free Also, just to check whether you had to manually free result_pointer , I called result_pointer.free after printing extracting the array and got this warning 另外,为了检查是否必须手动释放result_pointer ,我在打印解压缩数组后调用了result_pointer.free并获得了此警告

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

So it looks like you don't have to manually free result_pointer either. 所以看起来你不必手动释放result_pointer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM