面试题答案
一键面试1. Ruby数组传递给C函数
- 实现思路:
- 在Ruby中,数组是一个对象。通过Ruby的C API,可以获取数组对象的指针,然后遍历数组元素,根据元素类型进行相应处理。
- 利用
rb_ary_entry
函数可以获取数组指定索引位置的元素。
- 关键代码:
#include "ruby.h"
// 定义一个C函数,接收Ruby数组
VALUE my_function(VALUE ary) {
long len = RARRAY_LEN(ary);
for (long i = 0; i < len; i++) {
VALUE element = rb_ary_entry(ary, i);
// 这里可以根据element的类型进行相应处理,例如:
if (TYPE(element) == T_FIXNUM) {
long num = FIX2LONG(element);
// 对num进行处理
}
}
return Qnil;
}
在Ruby中注册这个函数:
require "rbconfig"
require "mkmf"
create_makefile('my_ext')
// extconf.c
#include "ruby.h"
void Init_my_ext() {
VALUE m = rb_define_module("MyExt");
rb_define_module_function(m, "my_function", my_function, 1);
}
2. C函数将修改后的数组返回给Ruby
- 实现思路:
- 在C函数中创建一个新的Ruby数组对象。
- 将处理后的元素逐个添加到新数组中。
- 最后返回这个新数组对象给Ruby。
- 关键代码:
#include "ruby.h"
// 定义一个C函数,接收Ruby数组并返回修改后的数组
VALUE my_function(VALUE ary) {
long len = RARRAY_LEN(ary);
VALUE new_ary = rb_ary_new();
for (long i = 0; i < len; i++) {
VALUE element = rb_ary_entry(ary, i);
// 对element进行处理,例如翻倍
if (TYPE(element) == T_FIXNUM) {
long num = FIX2LONG(element);
num = num * 2;
VALUE new_element = LONG2FIX(num);
rb_ary_push(new_ary, new_element);
}
}
return new_ary;
}
同样在Ruby中注册这个函数:
require "rbconfig"
require "mkmf"
create_makefile('my_ext')
// extconf.c
#include "ruby.h"
void Init_my_ext() {
VALUE m = rb_define_module("MyExt");
rb_define_module_function(m, "my_function", my_function, 1);
}
在Ruby中调用:
require 'my_ext'
ary = [1, 2, 3]
result = MyExt.my_function(ary)
puts result.inspect