我一直在使用OilyPNG(一组用于处理PNG的C扩展),我想开始添加一些自己的方法。因此,我编写了一个简单的小C扩展,它创建了类Hola
,并包含方法Hola.bonjour
(用简单的“hello”响应)和Hola.wazzup(input)
吐出输入权限背部。
OilyPNG是一个包含单个类:Canvas
的模块,其中包含一系列方法:decode_png_image_pass
,:from_data_url
,:from_rgb_stream
等。我想将我的方法(bonjour
和wazzup
)添加到Canvas
,以便我可以开始使用它们。我该怎么做呢?
这似乎是一个非常基本的Ruby问题,但我似乎无法在任何地方找到它。我已经尝试了(在许多其他事情中)以下内容:
module ChunkyPNG
class Canvas
include Hola
end
end
...但它会返回以下内容:
Error: #TypeError: wrong argument type Class (expected Module)
我想要做的就是创建一个新的Canvas对象,然后运行我的方法,即OilyPNG::Canvas.new.bonjour
,我完全陷入困境。
更新:用于生成扩展名的C代码
#include <ruby.h>
/* our new native method; it just returns the string "bonjour!" */
static VALUE hola_bonjour(VALUE self) {
return rb_str_new2("bonjour, Zack!");
}
void Init_hola(void) {
VALUE klass = rb_define_module("Hola"); /*DEFINED AS A MODULE*/
rb_define_singleton_method(klass, "bonjour", hola_bonjour, 0);
}
更新2:
最后让它工作 - 在C代码中使用rb_define module
,然后将方法定义为rb_define_method
(而不是单身)。然后构建gem,安装它,然后需要.so文件,然后打开OilyPNG以包含Hola模块,如下所示:
module OilyPNG
class Canvas < ChunkyPNG::Canvas
def your_method
puts "hello"
end
include Hola
end
end
然后将png文件作为测试对象加载:
test = OilyPNG::Canvas.from_file("C:/code/testfiles/orange.png"); nil
(nil是为了防止Sketchup在尝试将PNG对象发送到命令行时崩溃),然后测试输出:
test.bonjour
它有效!
答案 0 :(得分:1)
你说你
[...]编写了一个简单的小C扩展,创建了类“Hola”
所以Hola
是一个类。但是include
需要模块,而不是类。如果您希望Hola
修补include Hola
,则必须重建ChunkyPNG::Canvas
作为模块。
考虑这个例子:
class C
end
class D
include C
end
这将为您提供与您所看到的完全相同的TypeError
。但是,如果你说:
module M
end
class E
include M
end
然后它会正常工作。
答案 1 :(得分:0)
module OilyPNG
class Canvas < ChunkyPNG::Canvas # You must match the superclass when opening class and adding more definitions
def your_method
puts "hello"
end
include Hola # this will "insert" the Hola module at this point in the code... not sure what Hola contains so, not sure if that works or not.
end
end
查看OilyPNG的来源,上述应该有效......
不确定为什么会出现这个错误。鉴于这一点,这里的原因是:为了重新打开它,你必须匹配类,超类。
基于这篇文章:伟大的Peter Cooper的http://www.rubyinside.com/how-to-create-a-ruby-extension-in-c-in-under-5-minutes-100.html,我相信你应该使用rb_define_method
,而不是rb_define_singleton_method
如果您仍然遇到问题,请从彼得的例子开始,然后根据您的需要进行调整。