mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
210367ec88
which included commits to RCS files with non-trunk default branches. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@373 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1029 lines
27 KiB
Text
1029 lines
27 KiB
Text
.\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995
|
||
|
||
This document explains how to make extention modules for Ruby.
|
||
|
||
1¡¥Basic knowledge
|
||
|
||
In C, variables have types and data do not have types. In contrast,
|
||
Ruby variables do not have static type and data themselves have
|
||
types. So, data need to be converted across the languages.
|
||
|
||
Data in Ruby represented C type `VALUE'. Each VALUE data have its
|
||
data-type.
|
||
|
||
To retrieve an C data from the VALUE, you need to:
|
||
|
||
(1) Identify VALUE's data type
|
||
(2) Convert VALUE into C data
|
||
|
||
Converting to wrong data type may cause serious promblems.
|
||
|
||
|
||
1.1 Data-types
|
||
|
||
Ruby interpreter has data-types as below:
|
||
|
||
T_NIL nil
|
||
T_OBJECT ordinaly object
|
||
T_CLASS class
|
||
T_MODULE module
|
||
T_FLOAT floating point number
|
||
T_STRING string
|
||
T_REGEXP regular expression
|
||
T_ARRAY array
|
||
T_FIXNUM Fixnum(31bit integer)
|
||
T_HASH assosiative array
|
||
T_STRUCT (Ruby) structure
|
||
T_BIGNUM multi precision integer
|
||
T_TRUE true
|
||
T_FALSE false
|
||
T_DATA data
|
||
|
||
Otherwise, there are several other types used internally:
|
||
|
||
T_ICLASS
|
||
T_MATCH
|
||
T_VARMAP
|
||
T_SCOPE
|
||
T_NODE
|
||
|
||
Most of the types are represented by C structures.
|
||
|
||
1.2 Check Data Type of the VALUE
|
||
|
||
The macro TYPE() defined in ruby.h shows data-type of the VALUE.
|
||
TYPE() returns the constant number T_XXXX described above. To handle
|
||
data-types, the code will be like:
|
||
|
||
switch (TYPE(obj)) {
|
||
case T_FIXNUM:
|
||
/* process Fixnum */
|
||
break;
|
||
case T_STRING:
|
||
/* process String */
|
||
break;
|
||
case T_ARRAY:
|
||
/* process Array */
|
||
break;
|
||
default:
|
||
/* raise exception */
|
||
Fail("not valid value");
|
||
break;
|
||
}
|
||
|
||
There is the data-type check function.
|
||
|
||
void Check_Type(VALUE value, int type)
|
||
|
||
It raises an exception, if the VALUE does not have the type specified.
|
||
|
||
There are faster check-macros for fixnums and nil.
|
||
|
||
FIXNUM_P(obj)
|
||
NIL_P(obj)
|
||
|
||
1.3 Convert VALUE into C data
|
||
|
||
The data for type T_NIL, T_FALSE, T_TRUE are nil, true, false
|
||
respectively. They are singletons for the data type.
|
||
|
||
The T_FIXNUM data is the 31bit length fixed integer (63bit length on
|
||
some machines), which can be conver to the C integer by using
|
||
FIX2INT() macro. There also be NUM2INT() which converts any Ruby
|
||
numbers into C integer. The NUM2INT() macro includes type check, so
|
||
the exception will be raised if conversion failed.
|
||
|
||
Other data types have corresponding C structures, e.g. struct RArray
|
||
for T_ARRAY etc. VALUE of the type which has corresponding structure
|
||
can be cast to retrieve the pointer to the struct. The casting macro
|
||
RXXXX for each data type like RARRAY(obj). see "ruby.h".
|
||
|
||
For example, `RSTRING(size)->len' is the way to get the size of the
|
||
Ruby String object. The allocated region can be accessed by
|
||
`RSTRING(str)->ptr'. For arrays, `RARRAY(ary)->len' and
|
||
`RARRAY(ary)->ptr' respectively.
|
||
|
||
Notice: Do not change the value of the structure directly, unless you
|
||
are responsible about the result. It will be the cause of interesting
|
||
bugs.
|
||
|
||
1.4 Convert C data into VALUE
|
||
|
||
VALUE¤Î¼ÂºÝ¤Î¹½Â¤¤Ï
|
||
|
||
* FIXNUM¤Î¾ì¹ç
|
||
|
||
1bit±¦¥·¥Õ¥È¤·¤Æ¡¤LSB¤òΩ¤Æ¤ë¡¥
|
||
|
||
* ¤½¤Î¾¤Î¥Ý¥¤¥ó¥¿¤Î¾ì¹ç
|
||
|
||
¤½¤Î¤Þ¤ÞVALUE¤Ë¥¥ã¥¹¥È¤¹¤ë¡¥
|
||
|
||
¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥¤è¤Ã¤Æ¡¤LSB¤ò¥Á¥§¥Ã¥¯¤¹¤ì¤ÐVALUE¤¬FIXNUM¤«¤É
|
||
¤¦¤«¤ï¤«¤ë¤ï¤±¤Ç¤¹(¥Ý¥¤¥ó¥¿¤ÎLSB¤¬Î©¤Ã¤Æ¤¤¤Ê¤¤¤³¤È¤ò²¾Äꤷ¤Æ
|
||
¤¤¤ë)¡¥
|
||
|
||
¤Ç¤¹¤«¤é¡¤FIXNUM°Ê³°¤ÎRuby¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Î¹½Â¤ÂΤÏñ¤ËVALUE
|
||
¤Ë¥¥ã¥¹¥È¤¹¤ë¤À¤±¤ÇVALUE¤ËÊÑ´¹½ÐÍè¤Þ¤¹¡¥¤¿¤À¤·¡¤Ç¤°Õ¤Î¹½Â¤
|
||
ÂΤ¬VALUE¤Ë¥¥ã¥¹¥È½ÐÍè¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡¥¥¥ã¥¹¥È¤¹¤ë¤Î
|
||
¤ÏRuby¤ÎÃΤäƤ¤¤ë¹½Â¤ÂÎ(ruby.h¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ëstruct RXxxx
|
||
¤Î¤â¤Î)¤À¤±¤Ë¤·¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤¡¥
|
||
|
||
FIXNUM¤Ë´Ø¤·¤Æ¤ÏÊÑ´¹¥Þ¥¯¥í¤ò·Ðͳ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥C¤ÎÀ°¿ô
|
||
¤«¤éVALUE¤ËÊÑ´¹¤¹¤ë¥Þ¥¯¥í¤Ï°Ê²¼¤Î¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡¥É¬Íפ˱þ¤¸
|
||
¤Æ»È¤¤Ê¬¤±¤Æ¤¯¤À¤µ¤¤¡¥
|
||
|
||
INT2FIX() ¤â¤È¤ÎÀ°¿ô¤¬31bit°ÊÆâ¤Ë¼ý¤Þ¤ë»þ
|
||
INT2NUM() Ǥ°Õ¤ÎÀ°¿ô¤«¤éVALUE¤Ø
|
||
|
||
INT2NUM()¤ÏÀ°¿ô¤¬FIXNUM¤ÎÈϰϤ˼ý¤Þ¤é¤Ê¤¤¾ì¹ç¡¤Bignum¤ËÊÑ´¹
|
||
¤·¤Æ¤¯¤ì¤Þ¤¹(¤¬¡¤¾¯¤·ÃÙ¤¤)¡¥
|
||
|
||
1.5 Manipulate Ruby data
|
||
|
||
As I already told, it is not recommended to modify object's internal
|
||
structure. To manipulate objects, use functions supplied by Ruby
|
||
interpreter. Useful functions are listed below (not all):
|
||
|
||
String funtions
|
||
|
||
rb_str_new(char *ptr, int len)
|
||
|
||
Creates a new Ruby string.
|
||
|
||
rb_str_new2(char *ptr)
|
||
|
||
Creates a new Ruby string from C string. This is equivalent to
|
||
rb_str_new(ptr, strlen(ptr)).
|
||
|
||
rb_str_cat(VALUE str, char *ptr, int len)
|
||
|
||
Appends len bytes data from ptr to the Ruby string.
|
||
|
||
Array functions
|
||
|
||
rb_ary_new()
|
||
|
||
Creates an array with no element.
|
||
|
||
rb_ary_new2(int len)
|
||
|
||
Creates an array with no element, with allocating internal buffer
|
||
for len elements.
|
||
|
||
rb_ary_new3(int n, ...)
|
||
|
||
Creates an n-elements array from arguments.
|
||
|
||
rb_ary_new4(int n, VALUE *elts)
|
||
|
||
Creates an n-elements array from C array.
|
||
|
||
rb_ary_push(VALUE ary, VALUE val)
|
||
rb_ary_pop(VALUE ary)
|
||
rb_ary_shift(VALUE ary)
|
||
rb_ary_unshift(VALUE ary, VALUE val)
|
||
rb_ary_entry(VALUE ary, int idx)
|
||
|
||
Array operations. The first argument to each functions must be an
|
||
array. They may dump core if other types given.
|
||
|
||
2. Extend Ruby with C
|
||
|
||
¸¶ÍýŪ¤ËRuby¤Ç½ñ¤±¤ë¤³¤È¤ÏC¤Ç¤â½ñ¤±¤Þ¤¹¡¥Ruby¤½¤Î¤â¤Î¤¬C¤Çµ
|
||
½Ò¤µ¤ì¤Æ¤¤¤ë¤ó¤Ç¤¹¤«¤é¡¤ÅöÁ³¤È¤¤¤¨¤ÐÅöÁ³¤Ê¤ó¤Ç¤¹¤±¤É¡¥¤³¤³¤Ç
|
||
¤ÏRuby¤Î³ÈÄ¥¤Ë»È¤¦¤³¤È¤¬Â¿¤¤¤À¤í¤¦¤Èͽ¬¤µ¤ì¤ëµ¡Ç½¤òÃæ¿´¤Ë¾Ò
|
||
²ð¤·¤Þ¤¹¡¥
|
||
|
||
2.1 Add new features to Ruby
|
||
|
||
Ruby¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë´Ø¿ô¤ò»È¤¨¤ÐRuby¥¤¥ó¥¿¥×¥ê¥¿¤Ë¿·¤·¤¤µ¡Ç½
|
||
¤òÄɲ乤뤳¤È¤¬¤Ç¤¤Þ¤¹¡¥Ruby¤Ç¤Ï°Ê²¼¤Îµ¡Ç½¤òÄɲ乤ë´Ø¿ô¤¬
|
||
Ä󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡¥
|
||
|
||
* Classes, Modules
|
||
* Methods, Singleton Methods
|
||
* Constants
|
||
|
||
¤Ç¤Ï½ç¤Ë¾Ò²ð¤·¤Þ¤¹¡¥
|
||
|
||
2.1.1 Class/module definition
|
||
|
||
To define class or module, use functions below:
|
||
|
||
VALUE rb_define_class(char *name, VALUE super)
|
||
VALUE rb_define_module(char *name)
|
||
|
||
These functions return the newly created class ot module. You may
|
||
want to save this reference into the variable to use later.
|
||
|
||
2.1.2 Method/singleton method definition
|
||
|
||
To define methods or singleton methods, use functions below:
|
||
|
||
void rb_define_method(VALUE class, char *name,
|
||
VALUE (*func)(), int argc)
|
||
|
||
void rb_define_singleton_method(VALUE object, char *name,
|
||
VALUE (*func)(), int argc)
|
||
|
||
The `argc' represents the number of the arguments to the C function,
|
||
which must be less than 17. But I believe you don't need that much. :-)
|
||
|
||
If `argc' is negative, it specifies calling sequence, not number of
|
||
the arguments.
|
||
|
||
If argc is -1, the function will be called like:
|
||
|
||
VALUE func(int argc, VALUE *argv, VALUE obj)
|
||
|
||
where argc is the actual number of arguments, argv is the C array of
|
||
the arguments, and obj is the receiver.
|
||
|
||
if argc is -2, the arguments are passed in Ruby array. The function
|
||
will be called like:
|
||
|
||
VALUE func(VALUE obj, VALUE args)
|
||
|
||
where obj is the receiver, and args is the Ruby array containing
|
||
actual arguments.
|
||
|
||
There're two more functions to define method. One is to define
|
||
private method:
|
||
|
||
void rb_define_private_method(VALUE class, char *name,
|
||
VALUE (*func)(), int argc)
|
||
|
||
The other is to define module function, which is private AND singleton
|
||
method of the module. For example, sqrt is the module function
|
||
defined in Math module. It can be call in the form like:
|
||
|
||
Math.sqrt(4)
|
||
|
||
or
|
||
|
||
include Math
|
||
sqrt(4)
|
||
|
||
To define module function
|
||
|
||
void rb_define_module_function(VALUE module, char *name,
|
||
VALUE (*func)(), int argc)
|
||
|
||
Oh, in addition, function-like method, which is private method defined
|
||
in Kernel module, can be defined using:
|
||
|
||
void rb_define_global_function(char *name, VALUE (*func)(), int argc)
|
||
|
||
|
||
2.1.3 Constant definition
|
||
|
||
We have 2 functions to define constants:
|
||
|
||
void rb_define_const(VALUE class, char *name, VALUE val)
|
||
void rb_define_global_const(char *name, VALUE val)
|
||
|
||
The former is to define constant under specified class/module. The
|
||
latter is to define global constant.
|
||
|
||
2.2 Use Ruby features from C
|
||
|
||
There are several ways to invoke Ruby's features from C code.
|
||
|
||
2.2.1 Evaluate Ruby Program in String
|
||
|
||
Easiest way to call Ruby's function from C program is to evaluate the
|
||
string as Ruby program. This function will do the job.
|
||
|
||
VALUE rb_eval_string(char *str)
|
||
|
||
Evaluation is done under current context, thus current local variables
|
||
of the innermost method (which is defined by Ruby) can be accessed.
|
||
|
||
2.2.2 ID or Symbol
|
||
|
||
You can invoke methods directly, without parsing the string. First I
|
||
need to explain about symbols (which data type is ID). ID is the
|
||
integer number to represent Ruby's identifiers such as variable names.
|
||
It can be accessed from Ruby in the form like:
|
||
|
||
:Identifier
|
||
|
||
You can get the symbol value from string within C code, by using
|
||
|
||
rb_intern(char *name)
|
||
|
||
In addition, the symbols for one character operators (e.g +) is the
|
||
code for that character.
|
||
|
||
2.2.3 Invoke Ruby method from C
|
||
|
||
To invoke methods directly, you can use the function below
|
||
|
||
VALUE rb_funcall(VALUE recv, ID mid, int argc, ...)
|
||
|
||
This function invokes the method of the recv, which name is specified
|
||
by the symbol mid.
|
||
|
||
2.2.4 Accessing the variables and constants
|
||
|
||
C¤«¤é´Ø¿ô¤ò»È¤Ã¤Æ»²¾È¡¦¹¹¿·¤Ç¤¤ë¤Î¤Ï¡¤¥¯¥é¥¹Äê¿ô¡¤¥¤¥ó¥¹¥¿
|
||
¥ó¥¹ÊÑ¿ô¤Ç¤¹¡¥Âç°èÊÑ¿ô¤Ï°ìÉô¤Î¤â¤Î¤ÏC¤ÎÂç°èÊÑ¿ô¤È¤·¤Æ¥¢¥¯¥»
|
||
¥¹¤Ç¤¤Þ¤¹¡¥¥í¡¼¥«¥ëÊÑ¿ô¤ò»²¾È¤¹¤ëÊýË¡¤Ï¸ø³«¤·¤Æ¤¤¤Þ¤»¤ó¡¥
|
||
|
||
The functions to access/modify instance variables are below:
|
||
|
||
VALUE rb_ivar_get(VALUE obj, ID id)
|
||
VALUE rb_ivar_set(VALUE obj, ID id, VALUE val)
|
||
|
||
id must be the symbol, which can be retrieved by rb_intern().
|
||
|
||
To access the constants of the class/module:
|
||
|
||
VALUE rb_const_get(VALUE obj, ID id)
|
||
|
||
See 2.1.3 for defining new constant.
|
||
|
||
3. Informatin sharing between Ruby and C
|
||
|
||
C¸À¸ì¤ÈRuby¤Î´Ö¤Ç¾ðÊó¤ò¶¦Í¤¹¤ëÊýË¡¤Ë¤Ä¤¤¤Æ²òÀ⤷¤Þ¤¹¡¥
|
||
|
||
3.1 Ruby constant that C¤«¤é»²¾È¤Ç¤¤ëRuby¤ÎÄê¿ô
|
||
|
||
Following Ruby constants can be referred from C.
|
||
|
||
Qtrue
|
||
Qfalse
|
||
|
||
Boolean values. Qfalse is false in the C also (i.e. 0).
|
||
|
||
Qnil
|
||
|
||
Ruby nil in C scope.
|
||
|
||
3.2 Global variables shared between C and Ruby
|
||
|
||
C¤ÈRuby¤ÇÂç°èÊÑ¿ô¤ò»È¤Ã¤Æ¾ðÊó¤ò¶¦Í¤Ç¤¤Þ¤¹¡¥¶¦Í¤Ç¤¤ëÂç°è
|
||
ÊÑ¿ô¤Ë¤Ï¤¤¤¯¤Ä¤«¤Î¼ïÎब¤¢¤ê¤Þ¤¹¡¥¤½¤Î¤Ê¤«¤Ç¤â¤Ã¤È¤âÎɤ¯»È¤ï
|
||
¤ì¤ë¤È»×¤ï¤ì¤ë¤Î¤Ïrb_define_variable()¤Ç¤¹¡¥
|
||
|
||
void rb_define_variable(char *name, VALUE *var)
|
||
|
||
¤³¤Î´Ø¿ô¤ÏRuby¤ÈC¤È¤Ç¶¦Í¤¹¤ëÂç°èÊÑ¿ô¤òÄêµÁ¤·¤Þ¤¹¡¥ÊÑ¿ô̾¤¬
|
||
`$'¤Ç»Ï¤Þ¤é¤Ê¤¤»þ¤Ë¤Ï¼«Æ°Åª¤ËÄɲ䵤ì¤Þ¤¹¡¥¤³¤ÎÊÑ¿ô¤ÎÃͤòÊÑ
|
||
¹¹¤¹¤ë¤È¼«Æ°Åª¤ËRuby¤ÎÂбþ¤¹¤ëÊÑ¿ô¤ÎÃͤâÊѤï¤ê¤Þ¤¹¡¥
|
||
|
||
¤Þ¤¿Ruby¦¤«¤é¤Ï¹¹¿·¤Ç¤¤Ê¤¤ÊÑ¿ô¤â¤¢¤ê¤Þ¤¹¡¥¤³¤Îread only¤Î
|
||
ÊÑ¿ô¤Ï°Ê²¼¤Î´Ø¿ô¤ÇÄêµÁ¤·¤Þ¤¹¡¥
|
||
|
||
void rb_define_readonly_variable(char *name, VALUE *var)
|
||
|
||
¤³¤ì¤éÊÑ¿ô¤Î¾¤Ëhook¤ò¤Ä¤±¤¿Âç°èÊÑ¿ô¤òÄêµÁ¤Ç¤¤Þ¤¹¡¥hookÉÕ¤
|
||
¤ÎÂç°èÊÑ¿ô¤Ï°Ê²¼¤Î´Ø¿ô¤òÍѤ¤¤ÆÄêµÁ¤·¤Þ¤¹¡¥hookÉÕ¤Âç°èÊÑ¿ô¤Î
|
||
Ãͤλ²¾È¤äÀßÄê¤Ïhook¤Ç¹Ô¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡¥
|
||
|
||
void rb_define_hooked_variable(char *name, VALUE *var,
|
||
VALUE (*getter)(), VALUE (*setter)())
|
||
|
||
¤³¤Î´Ø¿ô¤ÏC¤Î´Ø¿ô¤Ë¤è¤Ã¤Æhook¤Î¤Ä¤±¤é¤ì¤¿Âç°èÊÑ¿ô¤òÄêµÁ¤·¤Þ
|
||
¤¹¡¥ÊÑ¿ô¤¬»²¾È¤µ¤ì¤¿»þ¤Ë¤Ï´Ø¿ôgetter¤¬¡¤ÊÑ¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì
|
||
¤¿»þ¤Ë¤Ï´Ø¿ôsetter¤¬¸Æ¤Ð¤ì¤ë¡¥hook¤ò»ØÄꤷ¤Ê¤¤¾ì¹ç¤Ïgetter¤ä
|
||
setter¤Ë0¤ò»ØÄꤷ¤Þ¤¹¡¥
|
||
|
||
# getter¤âsetter¤â0¤Ê¤é¤Ðrb_define_variable()¤ÈƱ¤¸¤Ë¤Ê¤ë¡¥
|
||
|
||
¤½¤ì¤«¤é¡¤C¤Î´Ø¿ô¤Ë¤è¤Ã¤Æ¼Â¸½¤µ¤ì¤ëRuby¤ÎÂç°èÊÑ¿ô¤òÄêµÁ¤¹¤ë
|
||
´Ø¿ô¤¬¤¢¤ê¤Þ¤¹¡¥
|
||
|
||
void rb_define_virtual_variable(char *name,
|
||
VALUE (*getter)(), VALUE (*setter)())
|
||
|
||
¤³¤Î´Ø¿ô¤Ë¤è¤Ã¤ÆÄêµÁ¤µ¤ì¤¿Ruby¤ÎÂç°èÊÑ¿ô¤¬»²¾È¤µ¤ì¤¿»þ¤Ë¤Ï
|
||
getter¤¬¡¤ÊÑ¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì¤¿»þ¤Ë¤Ïsetter¤¬¸Æ¤Ð¤ì¤Þ¤¹¡¥
|
||
|
||
The prototypes of the getter and setter functions are as following:
|
||
|
||
(*getter)(ID id, void *data, struct global_entry* entry);
|
||
(*setter)(VALUE val, ID id, void *data, struct global_entry* entry);
|
||
|
||
3.3 Encapsulate C data into Ruby object
|
||
|
||
C¤ÎÀ¤³¦¤ÇÄêµÁ¤µ¤ì¤¿¥Ç¡¼¥¿(¹½Â¤ÂÎ)¤òRuby¤Î¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æ
|
||
¼è¤ê°·¤¤¤¿¤¤¾ì¹ç¤¬¤¢¤ê¤¨¤Þ¤¹¡¥¤³¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¡¤Data¤È¤¤¤¦
|
||
Ruby¥ª¥Ö¥¸¥§¥¯¥È¤ËC¤Î¹½Â¤ÂÎ(¤Ø¤Î¥Ý¥¤¥ó¥¿)¤ò¤¯¤ë¤à¤³¤È¤ÇRuby
|
||
¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æ¼è¤ê°·¤¨¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡¥
|
||
|
||
Data¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¤Æ¹½Â¤ÂΤòRuby¥ª¥Ö¥¸¥§¥¯¥È¤Ë¥«¥×¥»¥ë
|
||
²½¤¹¤ë¤¿¤á¤Ë¤Ï¡¤°Ê²¼¤Î¥Þ¥¯¥í¤ò»È¤¤¤Þ¤¹¡¥
|
||
|
||
Data_Wrap_Struct(class,mark,free,ptr)
|
||
|
||
¤³¤Î¥Þ¥¯¥í¤ÎÌá¤êÃͤÏÀ¸À®¤µ¤ì¤¿Data¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¹¡¥
|
||
|
||
class¤Ï¤³¤ÎData¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¯¥é¥¹¤Ç¤¹¡¥ptr¤Ï¥«¥×¥»¥ë²½¤¹¤ë
|
||
C¤Î¹½Â¤ÂΤؤΥݥ¤¥ó¥¿¤Ç¤¹¡¥mark¤Ï¤³¤Î¹½Â¤ÂΤ¬Ruby¤Î¥ª¥Ö¥¸¥§
|
||
¥¯¥È¤Ø¤Î»²¾È¤¬¤¢¤ë»þ¤Ë»È¤¦´Ø¿ô¤Ç¤¹¡¥¤½¤Î¤è¤¦¤Ê»²¾È¤ò´Þ¤Þ¤Ê¤¤
|
||
»þ¤Ë¤Ï0¤ò»ØÄꤷ¤Þ¤¹¡¥
|
||
|
||
# ¤½¤Î¤è¤¦¤Ê»²¾È¤Ï´«¤á¤é¤ì¤Þ¤»¤ó¡¥
|
||
|
||
free¤Ï¤³¤Î¹½Â¤ÂΤ¬¤â¤¦ÉÔÍפˤʤä¿»þ¤Ë¸Æ¤Ð¤ì¤ë´Ø¿ô¤Ç¤¹¡¥¤³¤Î
|
||
´Ø¿ô¤¬¥¬¡¼¥Ù¡¼¥¸¥³¥ì¥¯¥¿¤«¤é¸Æ¤Ð¤ì¤Þ¤¹¡¥
|
||
|
||
C¤Î¹½Â¤ÂΤγäÅö¤ÈData¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®¤òƱ»þ¤Ë¹Ô¤¦¥Þ¥¯¥í¤È
|
||
¤·¤Æ°Ê²¼¤Î¤â¤Î¤¬Ä󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡¥
|
||
|
||
Data_Make_Struct(class, type, mark, free, sval)
|
||
|
||
¤³¤Î¥Þ¥¯¥í¤ÎÌá¤êÃͤÏÀ¸À®¤µ¤ì¤¿Data¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¹¡¥
|
||
|
||
class, mark, free¤ÏData_Wrap_Struct¤ÈƱ¤¸Æ¯¤¤ò¤·¤Þ¤¹¡¥type
|
||
¤Ï³ä¤êÅö¤Æ¤ëC¹½Â¤ÂΤη¿¤Ç¤¹¡¥³ä¤êÅö¤Æ¤é¤ì¤¿¹½Â¤ÂΤÏÊÑ¿ôsval
|
||
¤ËÂåÆþ¤µ¤ì¤Þ¤¹¡¥¤³¤ÎÊÑ¿ô¤Î·¿¤Ï (type*) ¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥
|
||
|
||
Data¥ª¥Ö¥¸¥§¥¯¥È¤«¤é¥Ý¥¤¥ó¥¿¤ò¼è¤ê½Ð¤¹¤Î¤Ï°Ê²¼¤Î¥Þ¥¯¥í¤òÍѤ¤
|
||
¤Þ¤¹¡¥
|
||
|
||
Data_Get_Struct(obj, type, sval)
|
||
|
||
C¤Î¹½Â¤ÂΤؤΥݥ¤¥ó¥¿¤ÏÊÑ¿ôsval¤ËÂåÆþ¤µ¤ì¤Þ¤¹¡¥
|
||
|
||
¤³¤ì¤é¤ÎData¤Î»È¤¤Êý¤Ï¤Á¤ç¤Ã¤Èʬ¤«¤ê¤Ë¤¯¤¤¤Î¤Ç¡¤¸å¤ÇÀâÌÀ¤¹¤ë
|
||
ÎãÂê¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡¥
|
||
|
||
4¡¥Example - Create dbm module
|
||
|
||
¤³¤³¤Þ¤Ç¤ÎÀâÌÀ¤Ç¤È¤ê¤¢¤¨¤º³ÈÄ¥¥é¥¤¥Ö¥é¥ê¤Ïºî¤ì¤ë¤Ï¤º¤Ç¤¹¡¥
|
||
Ruby¤Îext¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¹¤Ç¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ëdbm¥â¥¸¥å¡¼¥ë¤òÎã¤Ë
|
||
¤·¤ÆÃʳ¬Åª¤ËÀâÌÀ¤·¤Þ¤¹¡¥
|
||
|
||
(1) make the directory
|
||
|
||
% mkdir ext/dbm
|
||
|
||
Make a directory for the extension library under ext directory.
|
||
|
||
(2) create MANIFEST file
|
||
|
||
% cd ext/dbm
|
||
% touch MANIFEST
|
||
|
||
There should be MANIFEST file in the directory for the extension
|
||
library. Make empty file now.
|
||
|
||
(3) design the library
|
||
|
||
You need to design the library features, before making it.
|
||
|
||
(4) write C code.
|
||
|
||
³ÈÄ¥¥é¥¤¥Ö¥é¥êËÜÂΤȤʤëC¸À¸ì¤Î¥½¡¼¥¹¤ò½ñ¤¤Þ¤¹¡¥C¸À¸ì¤Î¥½¡¼
|
||
¥¹¤¬¤Ò¤È¤Ä¤Î»þ¤Ë¤Ï¡Ö¥â¥¸¥å¡¼¥ë̾.c¡×¤òÁª¤Ö¤ÈÎɤ¤¤Ç¤·¤ç¤¦¡¥C
|
||
¸À¸ì¤Î¥½¡¼¥¹¤¬Ê£¿ô¤Î¾ì¹ç¤Ë¤ÏµÕ¤Ë¡Ö¥â¥¸¥å¡¼¥ë̾.c¡×¤È¤¤¤¦¥Õ¥¡
|
||
¥¤¥ë̾¤ÏÈò¤±¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥¥ª¥Ö¥¸¥§¥¯¥È¥Õ¥¡¥¤¥ë¤È¥â¥¸¥å¡¼
|
||
¥ëÀ¸À®»þ¤ËÃæ´ÖŪ¤ËÀ¸À®¤µ¤ì¤ë¡Ö¥â¥¸¥å¡¼¥ë̾.o¡×¤È¤¤¤¦¥Õ¥¡¥¤¥ë
|
||
¤È¤¬¾×Æͤ¹¤ë¤«¤é¤Ç¤¹¡¥
|
||
|
||
Ruby¤Ï³ÈÄ¥¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤¹¤ë»þ¤Ë¡ÖInit_¥â¥¸¥å¡¼¥ë̾¡×¤È
|
||
¤¤¤¦´Ø¿ô¤ò¼«Æ°Åª¤Ë¼Â¹Ô¤·¤Þ¤¹¡¥dbm¥â¥¸¥å¡¼¥ë¤Î¾ì¹ç¡ÖInit_dbm¡×
|
||
¤Ç¤¹¡¥¤³¤Î´Ø¿ô¤ÎÃæ¤Ç¥¯¥é¥¹¡¤¥â¥¸¥å¡¼¥ë¡¤¥á¥½¥Ã¥É¡¤Äê¿ô¤Ê¤É¤Î
|
||
ÄêµÁ¤ò¹Ô¤¤¤Þ¤¹¡¥dbm.c¤«¤é°ìÉô°úÍѤ·¤Þ¤¹¡¥
|
||
|
||
--
|
||
Init_dbm()
|
||
{
|
||
/* define DBM class */
|
||
cDBM = rb_define_class("DBM", rb_cObject);
|
||
/* DBM includes Enumerate module */
|
||
rb_include_module(cDBM, rb_mEnumerable);
|
||
|
||
/* DBM has class method open(): arguments are received as C array */
|
||
rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1);
|
||
|
||
/* DBM instance method close(): no args */
|
||
rb_define_method(cDBM, "close", fdbm_close, 0);
|
||
/* DBM instance method []: 1 argument */
|
||
rb_define_method(cDBM, "[]", fdbm_fetch, 1);
|
||
:
|
||
|
||
}
|
||
--
|
||
|
||
DBM¥â¥¸¥å¡¼¥ë¤Ïdbm¤Î¥Ç¡¼¥¿¤ÈÂбþ¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Ë¤Ê¤ë¤Ï¤º¤Ç
|
||
¤¹¤«¤é¡¤C¤ÎÀ¤³¦¤Îdbm¤òRuby¤ÎÀ¤³¦¤Ë¼è¤ê¹þ¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡¥
|
||
|
||
|
||
dbm.c¤Ç¤ÏData_Make_Struct¤ò°Ê²¼¤Î¤è¤¦¤Ë»È¤Ã¤Æ¤¤¤Þ¤¹¡¥
|
||
|
||
--
|
||
struct dbmdata {
|
||
int di_size;
|
||
DBM *di_dbm;
|
||
};
|
||
|
||
|
||
obj = Data_Make_Struct(class,struct dbmdata,0,free_dbm,dbmp);
|
||
--
|
||
|
||
¤³¤³¤Ç¤Ïdbmstruct¹½Â¤ÂΤؤΥݥ¤¥ó¥¿¤òData¤Ë¥«¥×¥»¥ë²½¤·¤Æ¤¤
|
||
¤Þ¤¹¡¥DBM*¤òľÀÜ¥«¥×¥»¥ë²½¤·¤Ê¤¤¤Î¤Ïclose()¤·¤¿»þ¤Î½èÍý¤ò¹Í
|
||
¤¨¤Æ¤Î¤³¤È¤Ç¤¹¡¥
|
||
|
||
Data¥ª¥Ö¥¸¥§¥¯¥È¤«¤édbmstruct¹½Â¤ÂΤΥݥ¤¥ó¥¿¤ò¼è¤ê½Ð¤¹¤¿¤á
|
||
¤Ë°Ê²¼¤Î¥Þ¥¯¥í¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡¥
|
||
|
||
--
|
||
#define GetDBM(obj, dbmp) {\
|
||
Data_Get_Struct(obj, struct dbmdata, dbmp);\
|
||
if (dbmp->di_dbm == 0) closed_dbm();\
|
||
}
|
||
--
|
||
|
||
¤Á¤ç¤Ã¤ÈÊ£»¨¤Ê¥Þ¥¯¥í¤Ç¤¹¤¬¡¤Íפ¹¤ë¤Ëdbmdata¹½Â¤ÂΤΥݥ¤¥ó¥¿
|
||
¤Î¼è¤ê½Ð¤·¤È¡¤close¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Î¥Á¥§¥Ã¥¯¤ò¤Þ¤È¤á¤Æ¤¤
|
||
¤ë¤À¤±¤Ç¤¹¡¥
|
||
|
||
DBM¥¯¥é¥¹¤Ë¤Ï¤¿¤¯¤µ¤ó¥á¥½¥Ã¥É¤¬¤¢¤ê¤Þ¤¹¤¬¡¤Ê¬Îह¤ë¤È3¼ïÎà¤Î
|
||
°ú¿ô¤Î¼õ¤±Êý¤¬¤¢¤ê¤Þ¤¹¡¥¤Ò¤È¤Ä¤Ï°ú¿ô¤Î¿ô¤¬¸ÇÄê¤Î¤â¤Î¤Ç¡¤Îã¤È
|
||
¤·¤Æ¤Ïdelete¥á¥½¥Ã¥É¤¬¤¢¤ê¤Þ¤¹¡¥delete¥á¥½¥Ã¥É¤ò¼ÂÁõ¤·¤Æ¤¤¤ë
|
||
fdbm_delete()¤Ï¤³¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥
|
||
|
||
--
|
||
static VALUE
|
||
fdbm_delete(obj, keystr)
|
||
VALUE obj, keystr;
|
||
{
|
||
:
|
||
}
|
||
--
|
||
|
||
°ú¿ô¤Î¿ô¤¬¸ÇÄê¤Î¥¿¥¤¥×¤ÏÂè1°ú¿ô¤¬self¡¤Âè2°ú¿ô°Ê¹ß¤¬¥á¥½¥Ã¥É
|
||
¤Î°ú¿ô¤È¤Ê¤ê¤Þ¤¹¡¥
|
||
|
||
°ú¿ô¤Î¿ô¤¬ÉÔÄê¤Î¤â¤Î¤ÏC¤ÎÇÛÎó¤Ç¼õ¤±¤ë¤â¤Î¤ÈRuby¤ÎÇÛÎó¤Ç¼õ¤±
|
||
¤ë¤â¤Î¤È¤¬¤¢¤ê¤Þ¤¹¡¥dbm¥â¥¸¥å¡¼¥ë¤ÎÃæ¤Ç¡¤C¤ÎÇÛÎó¤Ç¼õ¤±¤ë¤â¤Î
|
||
¤ÏDBM¤Î¥¯¥é¥¹¥á¥½¥Ã¥É¤Ç¤¢¤ëopen()¤Ç¤¹¡¥¤³¤ì¤ò¼ÂÁõ¤·¤Æ¤¤¤ë´Ø
|
||
¿ôfdbm_s_open()¤Ï¤³¤¦¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥
|
||
|
||
--
|
||
static VALUE
|
||
fdbm_s_open(argc, argv, class)
|
||
int argc;
|
||
VALUE *argv;
|
||
VALUE class;
|
||
{
|
||
:
|
||
if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
|
||
mode = 0666; /* default value */
|
||
}
|
||
:
|
||
}
|
||
--
|
||
|
||
¤³¤Î¥¿¥¤¥×¤Î´Ø¿ô¤ÏÂè1°ú¿ô¤¬Í¿¤¨¤é¤ì¤¿°ú¿ô¤Î¿ô¡¤Âè2°ú¿ô¤¬Í¿¤¨
|
||
¤é¤ì¤¿°ú¿ô¤ÎÆþ¤Ã¤Æ¤¤¤ëÇÛÎó¤Ë¤Ê¤ê¤Þ¤¹¡¥self¤ÏÂè3°ú¿ô¤È¤·¤ÆÍ¿
|
||
¤¨¤é¤ì¤Þ¤¹¡¥
|
||
|
||
¤³¤ÎÇÛÎó¤ÇÍ¿¤¨¤é¤ì¤¿°ú¿ô¤ò²òÀϤ¹¤ë¤¿¤á¤Î´Ø¿ô¤¬open()¤Ç¤â»È¤ï
|
||
¤ì¤Æ¤¤¤ërb_scan_args()¤Ç¤¹¡¥Âè3°ú¿ô¤Ë»ØÄꤷ¤¿¥Õ¥©¡¼¥Þ¥Ã¥È¤Ë
|
||
½¾¤¤¡¤Âè4ÊÑ¿ô°Ê¹ß¤Ë»ØÄꤷ¤¿ÊÑ¿ô¤ËÃͤòÂåÆþ¤·¤Æ¤¯¤ì¤Þ¤¹¡¥¤³¤Î
|
||
¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï¡¤Âè1ʸ»úÌܤ¬¾Êά¤Ç¤¤Ê¤¤°ú¿ô¤Î¿ô¡¤Âè2ʸ»úÌܤ¬
|
||
¾Êά¤Ç¤¤ë°ú¿ô¤Î¿ô¡¤Âè3ʸ»úÌܤ¬Âбþ¤¹¤ëÁê¼ê¤¬Ìµ¤¤¤¢¤Þ¤ê¤Î°ú
|
||
¿ô¤¬¤¢¤ë¤«¤É¤¦¤«¤ò¼¨¤¹"*"¤Ç¤¹¡¥2ʸ»úÌܤÈ3ʸ»úÌܤϾÊά¤Ç¤¤Þ
|
||
¤¹¡¥dbm.c¤ÎÎã¤Ç¤Ï¡¤¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï"11"¤Ç¤¹¤«¤é¡¤°ú¿ô¤ÏºÇÄã1¤Ä
|
||
¤Ç¡¤2¤Ä¤Þ¤Çµö¤µ¤ì¤ë¤È¤¤¤¦°ÕÌ£¤Ë¤Ê¤ê¤Þ¤¹¡¥¾Êά¤µ¤ì¤Æ¤¤¤ë»þ¤Î
|
||
ÊÑ¿ô¤ÎÃͤÏnil(C¸À¸ì¤Î¥ì¥Ù¥ë¤Ç¤ÏQnil)¤Ë¤Ê¤ê¤Þ¤¹¡¥
|
||
|
||
Ruby¤ÎÇÛÎó¤Ç°ú¿ô¤ò¼õ¤±¼è¤ë¤â¤Î¤Ïindexes¤¬¤¢¤ê¤Þ¤¹¡¥¼ÂÁõ¤Ï¤³
|
||
¤¦¤Ç¤¹¡¥
|
||
|
||
--
|
||
static VALUE
|
||
fdbm_indexes(obj, args)
|
||
VALUE obj;
|
||
struct RArray *args;
|
||
{
|
||
:
|
||
}
|
||
--
|
||
|
||
Âè1°ú¿ô¤Ïself¡¤Âè2°ú¿ô¤ÏRuby¤ÎÇÛÎó¤Ç¤¹¡¥¤³¤³¤Ç¤Ï¥¥ã¥¹¥È¤ò¸º
|
||
¤é¤¹¤¿¤á struct RArray* ¤Ç¼õ¤±¤Æ¤¤¤Þ¤¹¤¬¡¤VALUE¤Ç¤âƱ¤¸¤³¤È
|
||
¤Ç¤¹¡¥
|
||
|
||
** Notice
|
||
|
||
GC should know about global variables which refers Ruby's objects, but
|
||
not exported to the Ruby world. You need to protect them by
|
||
|
||
void rb_global_variable(VALUE *var)
|
||
|
||
(5) prepare extconf.rb
|
||
|
||
¤â¤·¥Ç¥£¥ì¥¯¥È¥ê¤Ë¡Öextconf.rb¡×¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ì¤Ð¡¤
|
||
make»þ¤Ë¼Â¹Ô¤µ¤ì¤Þ¤¹¡¥¤Ê¤±¤ì¤ÐŬÅö¤ËMakefile¤¬À¸À®¤µ¤ì¤Þ¤¹¡¥
|
||
|
||
extconf.rb¤Ï¥â¥¸¥å¡¼¥ë¤Î¥³¥ó¥Ñ¥¤¥ë¤ËɬÍפʾò·ï¤Î¥Á¥§¥Ã¥¯¤Ê¤É
|
||
¤ò¹Ô¤¦¤³¤È¤¬ÌÜŪ¤Ç¤¹¡¥extconf.rb¤ÎÃæ¤Ç¤Ï°Ê²¼¤ÎRuby´Ø¿ô¤ò»È¤¦
|
||
¤³¤È¤¬½ÐÍè¤Þ¤¹¡¥
|
||
|
||
have_library(lib, func): ¥é¥¤¥Ö¥é¥ê¤Î¸ºß¥Á¥§¥Ã¥¯
|
||
have_func(func): ´Ø¿ô¤Î¸ºß¥Á¥§¥Ã¥¯
|
||
have_header(header): ¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤Î¸ºß¥Á¥§¥Ã¥¯
|
||
create_makefile(target): Makefile¤ÎÀ¸À®
|
||
|
||
°Ê²¼¤ÎÊÑ¿ô¤ò»È¤¦¤³¤È¤¬¤Ç¤¤Þ¤¹¡¥
|
||
|
||
$CFLAGS: ¥³¥ó¥Ñ¥¤¥ë»þ¤ËÄɲÃŪ¤Ë»ØÄꤹ¤ë¥Õ¥é¥°(-I¤Ê¤É)
|
||
$LDFLAGS: ¥ê¥ó¥¯»þ¤ËÄɲÃŪ¤Ë»ØÄꤹ¤ë¥Õ¥é¥°(-L¤Ê¤É)
|
||
|
||
¥â¥¸¥å¡¼¥ë¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¾ò·ï¤¬Â·¤ï¤Ê¤º¡¤¤½¤Î¥â¥¸¥å¡¼¥ë¤Ï¥³
|
||
¥ó¥Ñ¥¤¥ë¤·¤Ê¤¤»þ¤Ë¤Ïcreate_makefile¤ò¸Æ¤Ð¤Ê¤±¤ì¤ÐMakefile¤Ï
|
||
À¸À®¤µ¤ì¤º¡¤¥³¥ó¥Ñ¥¤¥ë¤â¹Ô¤ï¤ì¤Þ¤»¤ó¡¥
|
||
|
||
(6) prepare depend (optional)
|
||
|
||
¤â¤·¡¤¥Ç¥£¥ì¥¯¥È¥ê¤Ëdepend¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ì¤Ð¡¤
|
||
Makefile¤¬°Í¸´Ø·¸¤ò¥Á¥§¥Ã¥¯¤·¤Æ¤¯¤ì¤Þ¤¹¡¥
|
||
|
||
% gcc -MM *.c > depend
|
||
|
||
¤Ê¤É¤Çºî¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡¥¤¢¤Ã¤Æ»¤Ï̵¤¤¤Ç¤·¤ç¤¦¡¥
|
||
|
||
(7) MANIFEST¥Õ¥¡¥¤¥ë¤Ë¥Õ¥¡¥¤¥ë̾¤òÆþ¤ì¤ë
|
||
|
||
% ls > MANIFEST
|
||
% vi MANIFEST
|
||
|
||
*.o, *~¤Ê¤ÉÉÔɬÍפʥե¡¥¤¥ë°Ê³°¤ÏMANIFEST¤ËÄɲ䷤Ƥª¤¤Þ¤¹¡¥
|
||
make»þ¤Ë¤ÏMANIFEST¤ÎÆâÍƤϻ²¾È¤·¤Þ¤»¤ó¤Î¤Ç¡¤¶õ¤Î¤Þ¤Þ¤Ç¤âÌäÂê
|
||
¤Ïµ¯¤¤Þ¤»¤ó¤¬¡¤¥Ñ¥Ã¥±¡¼¥¸¥ó¥°¤Î»þ¤Ë»²¾È¤¹¤ë¤³¤È¤¬¤¢¤ë¤Î¤È¡¤
|
||
ɬÍפʥե¡¥¤¥ë¤ò¶èÊ̤Ǥ¤ë¤Î¤Ç¡¤ÍÑ°Õ¤·¤Æ¤ª¤¤¤¿Êý¤¬Îɤ¤¤Ç¤·¤ç
|
||
¤¦¡¥
|
||
|
||
(8) make
|
||
|
||
Ruby¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Çmake¤ò¼Â¹Ô¤¹¤ë¤ÈMakefile¤òÀ¸À®¤«¤émake¡¤
|
||
ɬÍפˤè¤Ã¤Æ¤Ï¤½¤Î¥â¥¸¥å¡¼¥ë¤ÎRuby¤Ø¤Î¥ê¥ó¥¯¤Þ¤Ç¼«Æ°Åª¤Ë¼Â¹Ô
|
||
¤·¤Æ¤¯¤ì¤Þ¤¹¡¥extconf.rb¤ò½ñ¤´¹¤¨¤ë¤Ê¤É¤·¤ÆMakefile¤ÎºÆÀ¸À®
|
||
¤¬É¬Íפʻþ¤Ï¤Þ¤¿Ruby¥Ç¥£¥ì¥¯¥È¥ê¤Çmake¤·¤Æ¤¯¤À¤µ¤¤¡¥
|
||
|
||
(9) debug
|
||
|
||
You may need to rb_debug the module. The modules can be linked
|
||
statically by adding directory name in the ext/Setup file,
|
||
so that you can inspect the module by the debugger.
|
||
|
||
(10) done, now you have the extension library
|
||
|
||
¸å¤Ï¤³¤Ã¤½¤ê»È¤¦¤Ê¤ê¡¤¹¤¯¸ø³«¤¹¤ë¤Ê¤ê¡¤Çä¤ë¤Ê¤ê¡¤¤´¼«Í³¤Ë¤ª
|
||
»È¤¤¤¯¤À¤µ¤¤¡¥Ruby¤Îºî¼Ô¤Ï³ÈÄ¥¥é¥¤¥Ö¥é¥ê¤Ë´Ø¤·¤Æ°ìÀڤθ¢Íø¤ò
|
||
¼çÄ¥¤·¤Þ¤»¤ó¡¥
|
||
|
||
Appendix A. Ruby¤Î¥½¡¼¥¹¥³¡¼¥É¤ÎʬÎà
|
||
|
||
Ruby¤Î¥½¡¼¥¹¤Ï¤¤¤¯¤Ä¤«¤ËʬÎह¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡¥¤³¤Î¤¦¤Á¥¯¥é
|
||
¥¹¥é¥¤¥Ö¥é¥ê¤ÎÉôʬ¤Ï´ðËÜŪ¤Ë³ÈÄ¥¥é¥¤¥Ö¥é¥ê¤ÈƱ¤¸ºî¤êÊý¤Ë¤Ê¤Ã
|
||
¤Æ¤¤¤Þ¤¹¡¥¤³¤ì¤é¤Î¥½¡¼¥¹¤Ïº£¤Þ¤Ç¤ÎÀâÌÀ¤Ç¤Û¤È¤ó¤ÉÍý²ò¤Ç¤¤ë¤È
|
||
»×¤¤¤Þ¤¹¡¥
|
||
|
||
ruby language core
|
||
|
||
class.c
|
||
error.c
|
||
eval.c
|
||
gc.c
|
||
object.c
|
||
parse.y
|
||
variable.c
|
||
|
||
utility functions
|
||
|
||
dln.c
|
||
fnmatch.c
|
||
glob.c
|
||
regex.c
|
||
st.c
|
||
util.c
|
||
|
||
ruby interpreter implementation
|
||
|
||
dmyext.c
|
||
inits.c
|
||
main.c
|
||
ruby.c
|
||
version.c
|
||
|
||
class library
|
||
|
||
array.c
|
||
bignum.c
|
||
compar.c
|
||
dir.c
|
||
enum.c
|
||
file.c
|
||
hash.c
|
||
io.c
|
||
math.c
|
||
numeric.c
|
||
pack.c
|
||
process.c
|
||
random.c
|
||
range.c
|
||
re.c
|
||
signal.c
|
||
sprintf.c
|
||
string.c
|
||
struct.c
|
||
time.c
|
||
|
||
Appendix B. ³ÈÄ¥ÍÑ´Ø¿ô¥ê¥Õ¥¡¥ì¥ó¥¹
|
||
|
||
C¸À¸ì¤«¤éRuby¤Îµ¡Ç½¤òÍøÍѤ¹¤ëAPI¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
|
||
|
||
** ·¿
|
||
|
||
VALUE
|
||
|
||
Ruby¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¸½¤¹¤ë·¿¡¥É¬Íפ˱þ¤¸¤Æ¥¥ã¥¹¥È¤·¤ÆÍѤ¤¤ë¡¥
|
||
ÁȤ߹þ¤ß·¿¤òɽ¸½¤¹¤ëC¤Î·¿¤Ïruby.h¤Ëµ½Ò¤·¤Æ¤¢¤ëR¤Ç»Ï¤Þ¤ë¹½Â¤
|
||
ÂΤǤ¢¤ë¡¥VALUE·¿¤ò¤³¤ì¤é¤Ë¥¥ã¥¹¥È¤¹¤ë¤¿¤á¤ËR¤Ç»Ï¤Þ¤ë¹½Â¤ÂÎ
|
||
̾¤òÁ´¤ÆÂçʸ»ú¤Ë¤·¤¿Ì¾Á°¤Î¥Þ¥¯¥í¤¬ÍÑ°Õ¤µ¤ì¤Æ¤¤¤ë¡¥
|
||
|
||
** Variables and constants
|
||
|
||
Qnil
|
||
|
||
const: nil object
|
||
|
||
Qtrue
|
||
|
||
const: Qtrue object(default true value)
|
||
|
||
Qfalse
|
||
|
||
const: Qfalse object
|
||
|
||
** C¥Ç¡¼¥¿¤Î¥«¥×¥»¥ë²½
|
||
|
||
Data_Wrap_Struct(VALUE class, void (*mark)(), void (*free)(), void *sval)
|
||
|
||
C¤ÎǤ°Õ¤Î¥Ý¥¤¥ó¥¿¤ò¥«¥×¥»¥ë²½¤·¤¿Ruby¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡¥¤³
|
||
¤Î¥Ý¥¤¥ó¥¿¤¬Ruby¤«¤é¥¢¥¯¥»¥¹¤µ¤ì¤Ê¤¯¤Ê¤Ã¤¿»þ¡¤free¤Ç»ØÄꤷ¤¿
|
||
´Ø¿ô¤¬¸Æ¤Ð¤ì¤ë¡¥¤Þ¤¿¡¤¤³¤Î¥Ý¥¤¥ó¥¿¤Î»Ø¤¹¥Ç¡¼¥¿¤¬Â¾¤ÎRuby¥ª¥Ö
|
||
¥¸¥§¥¯¥È¤ò»Ø¤·¤Æ¤¤¤ë¾ì¹ç¡¤mark¤Ë»ØÄꤹ¤ë´Ø¿ô¤Ç¥Þ¡¼¥¯¤¹¤ëɬÍ×
|
||
¤¬¤¢¤ë¡¥
|
||
|
||
Data_Make_Struct(class, type, mark, free, sval)
|
||
|
||
type·¿¤Î¥á¥â¥ê¤òmalloc¤·¡¤ÊÑ¿ôsval¤ËÂåÆþ¤·¤¿¸å¡¤¤½¤ì¤ò¥«¥×¥»
|
||
¥ë²½¤·¤¿¥Ç¡¼¥¿¤òÊÖ¤¹¥Þ¥¯¥í¡¥
|
||
|
||
Data_Get_Struct(data, type, sval)
|
||
|
||
data¤«¤étype·¿¤Î¥Ý¥¤¥ó¥¿¤ò¼è¤ê½Ð¤·ÊÑ¿ôsval¤ËÂåÆþ¤¹¤ë¥Þ¥¯¥í¡¥
|
||
|
||
** ¥¯¥é¥¹/¥â¥¸¥å¡¼¥ëÄêµÁ
|
||
|
||
VALUE rb_define_class(char *name, VALUE super)
|
||
|
||
super¤Î¥µ¥Ö¥¯¥é¥¹¤È¤·¤Æ¿·¤·¤¤Ruby¥¯¥é¥¹¤òÄêµÁ¤¹¤ë¡¥
|
||
|
||
VALUE rb_define_class_under(VALUE module, char *name, VALUE super)
|
||
|
||
super¤Î¥µ¥Ö¥¯¥é¥¹¤È¤·¤Æ¿·¤·¤¤Ruby¥¯¥é¥¹¤òÄêµÁ¤·¡¤module¤ÎÄê
|
||
¿ô¤È¤·¤ÆÄêµÁ¤¹¤ë¡¥
|
||
|
||
VALUE rb_define_module(char *name)
|
||
|
||
¿·¤·¤¤Ruby¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤¹¤ë¡¥
|
||
|
||
VALUE rb_define_module_under(VALUE module, char *name, VALUE super)
|
||
|
||
¿·¤·¤¤Ruby¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤·¡¤module¤ÎÄê¿ô¤È¤·¤ÆÄêµÁ¤¹¤ë¡¥
|
||
|
||
void rb_include_module(VALUE class, VALUE module)
|
||
|
||
¥â¥¸¥å¡¼¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¡¥class¤¬¤¹¤Ç¤Ëmodule¤ò¥¤¥ó¥¯¥ë¡¼
|
||
¥É¤·¤Æ¤¤¤ë»þ¤Ë¤Ï²¿¤â¤·¤Ê¤¤(¿½Å¥¤¥ó¥¯¥ë¡¼¥É¤Î¶Ø»ß)¡¥
|
||
|
||
void rb_extend_object(VALUE object, VALUE module)
|
||
|
||
¥ª¥Ö¥¸¥§¥¯¥È¤ò¥â¥¸¥å¡¼¥ë(¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥á¥½¥Ã¥É)¤Ç³ÈÄ¥¤¹¤ë¡¥
|
||
|
||
** Defining Global Variables
|
||
|
||
void rb_define_variable(char *name, VALUE *var)
|
||
|
||
Defines a global variable which is shared between C and Ruby. If name
|
||
contains the character which is not allowed to be part of the symbol,
|
||
it can't be seen from Ruby programs.
|
||
|
||
void rb_define_readonly_variable(char *name, VALUE *var)
|
||
|
||
Defines a read-only global variable. Works just like
|
||
rb_define_variable(), except defined variable is read-only.
|
||
|
||
void rb_define_virtual_variable(char *name,
|
||
VALUE (*getter)(), VALUE (*setter)())
|
||
|
||
Defines a virtual variable, whose behavior is defined by pair of C
|
||
functions. The getter function is called when the variable is
|
||
referred. The setter function is called when the value is set to the
|
||
variable. The prototype for getter/setter functions are:
|
||
|
||
VALUE getter(ID id)
|
||
void setter(VALUE val, ID id)
|
||
|
||
The getter function must return the value for the access.
|
||
|
||
void rb_define_hooked_variable(char *name, VALUE *var,
|
||
VALUE (*getter)(), VALUE (*setter)())
|
||
|
||
Defines hooked variable. It's virtual variable with C variable. The
|
||
getter is called as
|
||
|
||
VALUE getter(ID id, VALUE *var)
|
||
|
||
returning new value. The setter is called as
|
||
|
||
void setter(VALUE val, ID id, VALUE *var)
|
||
|
||
GC requires to mark the C global variables which hold Ruby values.
|
||
|
||
void rb_global_variable(VALUE *var)
|
||
|
||
Tells GC to protect these variables.
|
||
|
||
** Constant Definition
|
||
|
||
void rb_define_const(VALUE klass, char *name, VALUE val)
|
||
|
||
Defines a new constant under the class/module.
|
||
|
||
void rb_define_global_const(char *name, VALUE val)
|
||
|
||
Defines global contant. This is just work as
|
||
|
||
rb_define_const(cKernal, name, val)
|
||
|
||
** Method Definition
|
||
|
||
rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc)
|
||
|
||
¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥argc¤Ïself¤ò½ü¤¯°ú¿ô¤Î¿ô¡¥argc¤¬-1¤Î»þ,
|
||
´Ø¿ô¤Ë¤Ï°ú¿ô¤Î¿ô(self¤ò´Þ¤Þ¤Ê¤¤)¤òÂè1°ú¿ô, °ú¿ô¤ÎÇÛÎó¤òÂè2°ú
|
||
¿ô¤È¤¹¤ë·Á¼°¤ÇÍ¿¤¨¤é¤ì¤ë(Âè3°ú¿ô¤Ïself)¡¥argc¤¬-2¤Î»þ, Âè1°ú
|
||
¿ô¤¬self, Âè2°ú¿ô¤¬args(args¤Ï°ú¿ô¤ò´Þ¤àRuby¤ÎÇÛÎó)¤È¤¤¤¦·Á
|
||
¼°¤ÇÍ¿¤¨¤é¤ì¤ë¡¥
|
||
|
||
rb_define_private_method(VALUE class, char *name, VALUE (*func)(), int argc)
|
||
|
||
private¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥°ú¿ô¤Ïrb_define_method()¤ÈƱ¤¸¡¥
|
||
|
||
rb_define_singleton_method(VALUE class, char *name, VALUE (*func)(), int argc)
|
||
|
||
Æðۥ᥽¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥°ú¿ô¤Ïrb_define_method()¤ÈƱ¤¸¡¥
|
||
|
||
rb_scan_args(int atgc, VALUE *argv, char *fmt, ...)
|
||
|
||
argc,argv·Á¼°¤ÇÍ¿¤¨¤é¤ì¤¿°ú¿ô¤òʬ²ò¤¹¤ë¡¥fmt¤Ïɬ¿Ü°ú¿ô¤Î¿ô,
|
||
Éղðú¿ô¤Î¿ô, »Ä¤ê¤Î°ú¿ô¤¬¤¢¤ë¤«¤ò»ØÄꤹ¤ëʸ»úÎó¤Ç, "¿ô»ú¿ô
|
||
»ú*"¤È¤¤¤¦·Á¼°¤Ç¤¢¤ë¡¥ 2 ÈÖÌܤοô»ú¤È"*"¤Ï¤½¤ì¤¾¤ì¾Êά²Äǽ¤Ç
|
||
¤¢¤ë¡¥É¬¿Ü°ú¿ô¤¬°ì¤Ä¤â¤Ê¤¤¾ì¹ç¤Ï0¤ò»ØÄꤹ¤ë¡¥Âè3°ú¿ô°Ê¹ß¤ÏÊÑ
|
||
¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç, ³ºÅö¤¹¤ëÍ×ÁǤ¬¤½¤ÎÊÑ¿ô¤Ë³ÊǼ¤µ¤ì¤ë¡¥Éղðú
|
||
¿ô¤ËÂбþ¤¹¤ë°ú¿ô¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤ÏÊÑ¿ô¤ËQnil¤¬ÂåÆþ¤µ¤ì
|
||
¤ë¡¥
|
||
|
||
** Ruby¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·
|
||
|
||
VALUE rb_funcall(VALUE recv, ID mid, int narg, ...)
|
||
|
||
¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¡¥Ê¸»úÎ󤫤émid¤òÆÀ¤ë¤¿¤á¤Ë¤Ïrb_intern()¤ò»È¤¦¡¥
|
||
|
||
VALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv)
|
||
|
||
¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¡¥°ú¿ô¤òargc,argv·Á¼°¤ÇÅϤ¹¡¥
|
||
|
||
VALUE rb_eval_string(char *str)
|
||
|
||
ʸ»úÎó¤òRuby¤È¥¹¥¯¥ê¥×¥È¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¡¦¼Â¹Ô¤¹¤ë¡¥
|
||
|
||
ID rb_intern(char *name)
|
||
|
||
ʸ»úÎó¤ËÂбþ¤¹¤ëID¤òÊÖ¤¹¡¥
|
||
|
||
char *rb_id2name(ID id)
|
||
|
||
ID¤ËÂбþ¤¹¤ëʸ»úÎó¤òÊÖ¤¹(¥Ç¥Ð¥Ã¥°ÍÑ)¡¥
|
||
|
||
char *rb_class2name(VALUE class)
|
||
|
||
class¤Î̾Á°¤òÊÖ¤¹(¥Ç¥Ð¥Ã¥°ÍÑ)¡¥class¤¬Ì¾Á°¤ò»ý¤¿¤Ê¤¤»þ¤Ë¤Ï,
|
||
ÁÄÀè¤òÁ̤äÆ̾Á°¤ò»ý¤Ä¥¯¥é¥¹¤Î̾Á°¤òÊÖ¤¹¡¥
|
||
|
||
** ¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô
|
||
|
||
VALUE rb_iv_get(VALUE obj, char *name)
|
||
|
||
obj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ÎÃͤòÆÀ¤ë¡¥`@'¤Ç»Ï¤Þ¤é¤Ê¤¤¥¤¥ó¥¹¥¿¥ó¥¹
|
||
ÊÑ¿ô¤Ï Ruby¥×¥í¥°¥é¥à¤«¤é¥¢¥¯¥»¥¹¤Ç¤¤Ê¤¤¡Ö±£¤ì¤¿¡×¥¤¥ó¥¹¥¿
|
||
¥ó¥¹ÊÑ¿ô¤Ë¤Ê¤ë¡¥
|
||
|
||
VALUE rb_iv_set(VALUE obj, char *name, VALUE val)
|
||
|
||
obj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤òval¤Ë¥»¥Ã¥È¤¹¤ë¡¥
|
||
|
||
** À©¸æ¹½Â¤
|
||
|
||
VALUE rb_iterate(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2)
|
||
|
||
func2¤ò¥Ö¥í¥Ã¥¯¤È¤·¤ÆÀßÄꤷ, func1¤ò¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ö¡¥
|
||
func1¤Ë¤Ï arg1¤¬°ú¿ô¤È¤·¤ÆÅϤµ¤ì, func2¤Ë¤ÏÂè1°ú¿ô¤Ë¥¤¥Æ¥ì¡¼
|
||
¥¿¤«¤éÍ¿¤¨¤é¤ì¤¿ÃÍ, Âè2°ú¿ô¤Ëarg2¤¬ÅϤµ¤ì¤ë¡¥
|
||
|
||
VALUE rb_yield(VALUE val)
|
||
|
||
val¤òÃͤȤ·¤Æ¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯¤ò¸Æ¤Ó½Ð¤¹¡¥
|
||
|
||
VALUE rb_rescue(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2)
|
||
|
||
´Ø¿ôfunc1¤òarg1¤ò°ú¿ô¤Ë¸Æ¤Ó½Ð¤¹¡¥func1¤Î¼Â¹ÔÃæ¤ËÎã³°¤¬È¯À¸¤·
|
||
¤¿»þ¤Ë¤Ï func2¤òarg2¤ò°ú¿ô¤È¤·¤Æ¸Æ¤Ö¡¥Ìá¤êÃͤÏÎã³°¤¬È¯À¸¤·¤Ê
|
||
¤«¤Ã¤¿»þ¤Ïfunc1¤ÎÌá¤êÃÍ, Îã³°¤¬È¯À¸¤·¤¿»þ¤Ë¤Ïfunc2¤ÎÌá¤êÃͤÇ
|
||
¤¢¤ë¡¥
|
||
|
||
VALUE rb_ensure(VALUE (*func1)(), void *arg1, void (*func2)(), void *arg2)
|
||
|
||
´Ø¿ôfunc1¤òarg1¤ò°ú¿ô¤È¤·¤Æ¼Â¹Ô¤·, ¼Â¹Ô½ªÎ»¸å(¤¿¤È¤¨Îã³°¤¬È¯
|
||
À¸¤·¤Æ¤â) func2¤òarg2¤ò°ú¿ô¤È¤·¤Æ¼Â¹Ô¤¹¤ë¡¥Ìá¤êÃͤÏfunc1¤ÎÌá
|
||
¤êÃͤǤ¢¤ë(Îã³°¤¬È¯À¸¤·¤¿»þ¤ÏÌá¤é¤Ê¤¤)¡¥
|
||
|
||
** Îã³°¡¦¥¨¥é¡¼
|
||
|
||
void rb_warning(char *fmt, ...)
|
||
|
||
rb_verbose»þ¤Ëɸ½à¥¨¥é¡¼½ÐÎϤ˷ٹð¾ðÊó¤òɽ¼¨¤¹¤ë¡¥°ú¿ô¤Ïprintf()¤ÈƱ¤¸¡¥
|
||
|
||
void rb_raise(rb_eRuntimeError, char *fmt, ...)
|
||
|
||
Îã³°¤òȯÀ¸¤µ¤»¤ë¡¥°ú¿ô¤Ïprintf()¤ÈƱ¤¸¡¥
|
||
|
||
void rb_fatal(char *fmt, ...)
|
||
|
||
Ã×̿ŪÎã³°¤òȯÀ¸¤µ¤»¤ë¡¥Ä̾ï¤ÎÎã³°½èÍý¤Ï¹Ô¤Ê¤ï¤ì¤º, ¥¤¥ó¥¿¡¼
|
||
¥×¥ê¥¿¤¬½ªÎ»¤¹¤ë(¤¿¤À¤·ensure¤Ç»ØÄꤵ¤ì¤¿¥³¡¼¥É¤Ï½ªÎ»Á°¤Ë¼Â
|
||
¹Ô¤µ¤ì¤ë)¡¥
|
||
|
||
void rb_bug(char *fmt, ...)
|
||
|
||
¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Ê¤É¥×¥í¥°¥é¥à¤Î¥Ð¥°¤Ç¤·¤«È¯À¸¤¹¤ë¤Ï¤º¤Î¤Ê¤¤¾õ
|
||
¶·¤Î»þ¸Æ¤Ö¡¥¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Ï¥³¥¢¥À¥ó¥×¤·Ä¾¤Á¤Ë½ªÎ»¤¹¤ë¡¥Îã³°
|
||
½èÍý¤Ï°ìÀڹԤʤï¤ì¤Ê¤¤¡¥
|
||
|
||
** Initialize and Starts the Interpreter
|
||
|
||
The embedding API are below (not needed for extension libraries):
|
||
|
||
void ruby_init(int argc, char **argv, char **envp)
|
||
|
||
Initializes the interpreter.
|
||
|
||
void ruby_run()
|
||
|
||
Starts execution of the interpreter.
|
||
|
||
void ruby_script(char *name)
|
||
|
||
Specifies the name of the script ($0).
|
||
|
||
Appendix B. Functions Available in extconf.rb
|
||
|
||
extconf.rb¤ÎÃæ¤Ç¤ÏÍøÍѲÄǽ¤Ê¥³¥ó¥Ñ¥¤¥ë¾ò·ï¥Á¥§¥Ã¥¯¤Î´Ø¿ô¤Ï°Ê
|
||
²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
|
||
|
||
have_library(lib, func)
|
||
|
||
Checks whether library which contains specified function exists.
|
||
Returns true if the library exists.
|
||
|
||
have_func(func)
|
||
|
||
Checks whether func exists. Returns true if the function exists. To
|
||
check functions in the additional library, you need to check that
|
||
library first using have_library().
|
||
|
||
have_header(header)
|
||
|
||
Checks for the header files. Returns true if the header file exists.
|
||
|
||
create_makefile(target)
|
||
|
||
Generates the Makefile for the extension library. If you don't invoke
|
||
this method, the compilation will not be done.
|
||
|
||
/*
|
||
* Local variables:
|
||
* fill-column: 60
|
||
* end:
|
||
*/
|