标签: ruby-c-extension

(U)Ruby Extensions:rb_gc_mark()和实例变量

我正在编写一个定义类的ruby扩展.如果我Data_Wrap_Struct()用来实现我的回调rb_define_alloc_func(),我是否需要手动标记并释放实例变量?或者这仍然是为我处理的?

c ruby mark-and-sweep ruby-c-extension

6
推荐指数
1
解决办法
898
查看次数

Ruby c扩展:如何捕获所有异常,包括不是StandardErrors的东西?

在红宝石中,

begin
  # ...
rescue
  # ...
end
Run Code Online (Sandbox Code Playgroud)

不会捕获不是子类的异常StandardError.在C中,

rb_rescue(x, Qnil, y, Qnil);

VALUE x(void) { /* ... */ return Qnil; }
VALUE y(void) { /* ... */ return Qnil; }
Run Code Online (Sandbox Code Playgroud)

会做同样的事情.我如何rescue Exception => e从ruby C扩展(而不仅仅是rescue => e)?

c ruby exception-handling rescue ruby-c-extension

6
推荐指数
1
解决办法
719
查看次数

如何在Ruby 1.9 C扩展中将块转换为Proc?

我正在编写Ruby 1.9 C扩展,我想在ruby中执行以下操作:

notifier = Notifier.new
notifier.on 'click' do
  puts "clicked!"
end
Run Code Online (Sandbox Code Playgroud)

现在问题是在C方法上,我只"接收"一个块,据我所知,它甚至不是一个参数:我只能用来调用rb_yield.

所以我的问题是:在Ruby 1.9 C扩展上是否有办法将块转换为proc或者其他东西,所以我可以将它存储在我的模块中,并在我想要/需要它时稍后调用它?就像一个异步回调!

我已经使用Procs/lambdas实现了这个,但是直接使用块语法真是太丑了.

c ruby block ruby-1.9 ruby-c-extension

6
推荐指数
1
解决办法
539
查看次数

如何rb_protect ruby​​中的所有内容

我想从我自己的C代码中调用ruby代码.如果引发异常,我必须rb_protect我调用的ruby代码.rb_protect看起来像这样:

VALUE rb_protect(VALUE (* proc) (VALUE), VALUE data, int * state)
Run Code Online (Sandbox Code Playgroud)

所以proc必须是一个接受VALUE参数和返回的函数VALUE.我必须调用许多不能以这种方式工作的函数.他怎么能rb_protect提出例外呢?

我曾想过Data_Make_Struct用来将所有东西都包装成一个ruby对象并在其上调用方法.Data_Make_Struct本身可以提出例外.我怎么样rb_protect Data_Make_Struct

ruby ruby-c-extension

6
推荐指数
1
解决办法
928
查看次数

无法创建C++ ruby​​扩展

我在创建ruby扩展以导出我在OSX下写入ruby的C++库时遇到问题.这个简单的例子:

#include <boost/regex.hpp>

extern "C" void Init_bayeux()
{
    boost::regex expression("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?");
}
Run Code Online (Sandbox Code Playgroud)

导致抛出bad_cast异常:

#0  0x00000001014663bd in __cxa_throw ()
#1  0x00000001014cf6b2 in __cxa_bad_cast ()
#2  0x00000001014986f9 in std::use_facet<std::collate<char> > ()
#3  0x0000000101135a4f in boost::re_detail::cpp_regex_traits_base<char>::imbue (this=0x7fff5fbfe4d0, l=@0x7fff5fbfe520) at cpp_regex_traits.hpp:218
#4  0x0000000101138d42 in cpp_regex_traits_base (this=0x7fff5fbfe4d0, l=@0x7fff5fbfe520) at cpp_regex_traits.hpp:173
#5  0x000000010113eda6 in boost::re_detail::create_cpp_regex_traits<char> (l=@0x7fff5fbfe520) at cpp_regex_traits.hpp:859
#6  0x0000000101149bee in cpp_regex_traits (this=0x101600200) at cpp_regex_traits.hpp:880
#7  0x0000000101142758 in regex_traits (this=0x101600200) at regex_traits.hpp:75
#8  0x000000010113d68c in regex_traits_wrapper (this=0x101600200) at regex_traits.hpp:169
#9  0x000000010113bae1 in regex_data (this=0x101600060) at basic_regex.hpp:166
#10 …
Run Code Online (Sandbox Code Playgroud)

c++ ruby macos boost ruby-c-extension

6
推荐指数
1
解决办法
839
查看次数

如何避免Ruby扩展中的跨线程违规?

我正在编写一个C扩展,提供Ruby和异步I/O库之间的接口.在我的代码上运行测试时,我经常会遇到错误,包括(但不限于):

[BUG] cross-thread violation in rb_thread_schedule()
Run Code Online (Sandbox Code Playgroud)

异步IO意味着我的C扩展需要从多个线程(而不是主解释器线程)向ruby传递消息.在此过程中如何避免这些线程安全违规?

c ruby multithreading ruby-c-extension

5
推荐指数
1
解决办法
596
查看次数

mkmf在编译C扩展名时会忽略子文件夹中的文件

我想这样组织C源代码:

+ /
|
|___ + ext
|    |
|    |___ + native_extension
|         |
|         |___ + lib
|         |    |
|         |    |___ (Source files are kept in here - may contain sub-folders)
|         |
|         |___ native_extension.c
|         |___ native_extension.h
|         |___ extconf.rb
|
|___ + lib
|    |
|    |___ (Ruby source code)
|
|___ Rakefile
Run Code Online (Sandbox Code Playgroud)

我无法让此设置正确使用mkmfnative_extension/lib中包含的中的文件native_extension.c,将被完全忽略。

构建扩展时,仅native_extension.{h,c}会进行编译,并且native_extension.{so,dll}在尝试运行扩展程序时出现不完整的符号查找错误。

有什么办法可以使这项工作吗?

c ruby mkmf ruby-c-extension

5
推荐指数
2
解决办法
649
查看次数

在开发带有C扩展的rubygem时,如何使用Rspec在本地进行测试?

我正在写一个包含C扩展的gem.通常当我写一个gem时,我会遵循TDD的过程,在那里我将编写一个失败的规范,然后处理代码直到它通过等等......

使用我在"ext/mygem/mygem.c"中的C扩展和在gemspec的"扩展"中配置的有效extconf.rb,如何运行我的规范并仍然加载了我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?

这可能是一个愚蠢的问题,但是从我的gem的开发源代码树里面输入'bundle install'并没有构建任何原生扩展.当我手动运行时,ruby ext/mygem/extconf.rb我得到一个Makefile(在整个项目的根目录中),当我运行时make,我确实得到了一个共享对象(同样,在整个项目的根目录中).我必须遵循错误的工作流程,因为我知道.so应该放在lib /下.除非我只是想在开发过程中手工做到这一点?

ruby rubygems extconf.rb ruby-c-extension

5
推荐指数
1
解决办法
806
查看次数

如何从C扩展中打印值?

每个Ruby对象都是VALUEC中的类型.如何以可读的方式打印它?

有关调试Ruby C扩展的任何其他提示都是受欢迎的.

c ruby debugging ruby-c-extension

5
推荐指数
2
解决办法
732
查看次数

为什么我从ruby数组中提取的值到我的c扩展名错了?

这个方法只是验证我能够正确地看到ruby数组的元素.

static VALUE 
print_cards(self) 
  VALUE self;
{
    VALUE cards;
    int i;

    cards = rb_ivar_get(self, rb_intern("@cards"));
    VALUE *ary_ptr = RARRAY_PTR(cards);
    int ary_length = RARRAY_LEN(cards);

    for(i=0; i< ary_length; i++)
        printf("%d\n", ary_ptr[i]);

  return Qnil;
}

void Init_ev() {
    rb_eval_string("require './lib/ev/pair_counter'");
    VALUE PairCounter = rb_path2class("EV::PairCounter");
    rb_define_method(PairCounter, "print_cards", print_cards, 0);
}
Run Code Online (Sandbox Code Playgroud)

但是当我使用该方法时,数组的元素是错误的.奇怪的是,它看起来并不像我得到某种地址信息,因为打印的数字大小大致与ruby数组中的数字大小相对应.每次创建新对象并运行print_cards时,数字也是一致的.

ruby-1.9.2-p180 :001 > p = EV::PairCounter.new   #=> #<EV::PairCounter:0x000001046a10f8 @pairs={}, @cards=[]>
ruby-1.9.2-p180 :002 > p.add_card(1)   #=> 1
ruby-1.9.2-p180 :003 > p.print_cards
3                                      #=> nil
ruby-1.9.2-p180 :004 > p.add_card(5)   #=> 2
ruby-1.9.2-p180 :005 > p.add_card(88) …
Run Code Online (Sandbox Code Playgroud)

c ruby ruby-c-extension

4
推荐指数
1
解决办法
102
查看次数