我正在尝试按照本教程在ruby gems http://guides.rubygems.org/gems-with-extensions/中构建c扩展。
我有以下文件:
require "mkmf"
abort "missing malloc()" unless have_func "malloc"
abort "missing free()" unless have_func "free"
create_makefile "my_malloc/my_malloc"
#include <ruby.h>
struct my_malloc {
size_t size;
void *ptr;
};
static void
my_malloc_free(void *p) {
struct my_malloc *ptr = p;
if (ptr->size > 0)
free(ptr->ptr);
}
static VALUE
my_malloc_alloc(VALUE klass) {
VALUE obj;
struct my_malloc *ptr;
obj = Data_Make_Struct(klass, struct my_malloc, NULL, my_malloc_free, ptr);
ptr->size = 0;
ptr->ptr = NULL;
return obj;
}
static VALUE
my_malloc_init(VALUE self, VALUE size) {
struct my_malloc *ptr;
size_t requested = NUM2SIZET(size);
if (0 == requested)
rb_raise(rb_eArgError, "unable to allocate 0 bytes");
Data_Get_Struct(self, struct my_malloc, ptr);
ptr->ptr = malloc(requested);
if (NULL == ptr->ptr)
rb_raise(rb_eNoMemError, "unable to allocate %ld bytes", requested);
ptr->size = requested;
return self;
}
static VALUE
my_malloc_release(VALUE self) {
struct my_malloc *ptr;
Data_Get_Struct(self, struct my_malloc, ptr);
if (0 == ptr->size)
return self;
ptr->size = 0;
free(ptr->ptr);
return self;
}
void
Init_my_malloc(void) {
VALUE cMyMalloc;
cMyMalloc = rb_const_get(rb_cObject, rb_intern("MyMalloc"));
rb_define_alloc_func(cMyMalloc, my_malloc_alloc);
rb_define_method(cMyMalloc, "initialize", my_malloc_init, 1);
rb_define_method(cMyMalloc, "free", my_malloc_release, 0);
}
我执行以下操作来构建扩展程序:
$ cd ext/my_malloc
$ ruby extconf.rb
checking for malloc()... yes
checking for free()... yes
creating Makefile
$ make
compiling my_malloc.c
linking shared-object my_malloc.bundle
$ cd ../..
$ ruby -Ilib:ext -r my_malloc -e "p MyMalloc.new(5).free"
但是,我在最后一个命令上收到以下错误:
/Users/Daniel/.rbenv/versions/2.1.6/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- my_malloc (LoadError)
from
/Users/Daniel/.rbenv/versions/2.1.6/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
注意,我使用rbenv,我尝试过运行rbenv rehash,我正在运行2.1.6版。
答案 0 :(得分:2)
正确的shell命令是:
ruby -Iext/my_malloc -r my_malloc -e "p MyMalloc.new(5).free"
该代码还有其他一些错误。正确
rb_raise(rb_eNoMemError, "unable to allocate %ld bytes", requested);
到
rb_raise(rb_eNoMemError, "unable to allocate %" PRIuSIZE " bytes", requested);
由于requested
的类型为size_t
,而long
不是PRIuSIZE
,"ruby/ruby.h"
是非标准的,并在cMyMalloc = rb_const_get(rb_cObject, rb_intern("MyMalloc"));
中定义。和
cMyMalloc = rb_define_class("MyMalloc", rb_cObject);
到
MyMalloc
实际定义$(document).ready(function() {
$('#firstvalue').addClass('user-click');
$('#usr').val("(" + $("#firstTag").text() + ")");
$('#demolist li a').on('click', function() {
$('.user-click').removeClass('user-click');
$(this).find('.user-check').addClass('user-click');
$('#usr').val("(" + $(this).text() + ")");
});
});
类。