我正在编写一个定义类的ruby扩展.如果我Data_Wrap_Struct()用来实现我的回调rb_define_alloc_func(),我是否需要手动标记并释放实例变量?或者这仍然是为我处理的?
在红宝石中,
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)?
我正在编写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代码.如果引发异常,我必须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扩展以导出我在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和异步I/O库之间的接口.在我的代码上运行测试时,我经常会遇到错误,包括(但不限于):
[BUG] cross-thread violation in rb_thread_schedule()
Run Code Online (Sandbox Code Playgroud)
异步IO意味着我的C扩展需要从多个线程(而不是主解释器线程)向ruby传递消息.在此过程中如何避免这些线程安全违规?
我想这样组织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)
我无法让此设置正确使用mkmf。native_extension/lib中包含的中的文件native_extension.c,将被完全忽略。
构建扩展时,仅native_extension.{h,c}会进行编译,并且native_extension.{so,dll}在尝试运行扩展程序时出现不完整的符号查找错误。
有什么办法可以使这项工作吗?
我正在写一个包含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对象都是VALUEC中的类型.如何以可读的方式打印它?
有关调试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)