Sophie

Sophie

distrib > CentOS > 5 > x86_64 > by-pkgid > 6d36cb72372cfb7c8fee63f4d6dc0530 > files > 647

ruby-docs-1.8.5-31.el5_9.x86_64.rpm

<?xml version="1.0" encoding="EUC-JP" ?>
<!DOCTYPE html 
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ruby-src:README.EXT</title>
<meta http-equiv="Content-type" content="text/html; charset=EUC-JP" />
<link href="default.css" type="text/css" rel="stylesheet" />
<link href="refm475.html" rel="next" />
<link href="refm473.html" rel="prev" />
<link href="index.html" rel="start" />

</head>
<body>
<div class="navigator"><span class="navigator">[<a href="index.html">MAIN</a>][<a href="refm482.html">INDEX</a>][<a href="refm483.html">KEYWORD</a>][<a href="refm594.html">METHOD</a>(<a href="refm633.html">NC</a>)]&nbsp;&nbsp;&nbsp;[<a href="index.html">TOP</a>][<a href="index.html">UP</a>][<a href="refm473.html">&lt;-PREV</a>][<a href="refm475.html">NEXT-&gt;</a>]</span></div>
<hr />

<h1>ruby-src:README.EXT</h1>
.\&quot;&nbsp;README.EXT&nbsp;-&nbsp;&nbsp;-*-&nbsp;Text&nbsp;-*-&nbsp;created&nbsp;at:&nbsp;Mon&nbsp;Aug&nbsp;&nbsp;7&nbsp;16:45:54&nbsp;JST&nbsp;1995<br />
<br />
This&nbsp;document&nbsp;explains&nbsp;how&nbsp;to&nbsp;make&nbsp;extension&nbsp;libraries&nbsp;for&nbsp;Ruby.<br />
<br />
1.&nbsp;Basic&nbsp;knowledge<br />
<br />
In&nbsp;C,&nbsp;variables&nbsp;have&nbsp;types&nbsp;and&nbsp;data&nbsp;do&nbsp;not&nbsp;have&nbsp;types.&nbsp;&nbsp;In&nbsp;contrast,<br />
Ruby&nbsp;variables&nbsp;do&nbsp;not&nbsp;have&nbsp;a&nbsp;static&nbsp;type,&nbsp;and&nbsp;data&nbsp;themselves&nbsp;have<br />
types,&nbsp;so&nbsp;data&nbsp;will&nbsp;need&nbsp;to&nbsp;be&nbsp;converted&nbsp;between&nbsp;the&nbsp;languages.<br />
<br />
Data&nbsp;in&nbsp;Ruby&nbsp;are&nbsp;represented&nbsp;by&nbsp;C&nbsp;type&nbsp;`VALUE'.&nbsp;&nbsp;Each&nbsp;VALUE&nbsp;data&nbsp;has<br />
its&nbsp;data-type.<br />
<br />
To&nbsp;retrieve&nbsp;C&nbsp;data&nbsp;from&nbsp;a&nbsp;VALUE,&nbsp;you&nbsp;need&nbsp;to:<br />
<br />
&nbsp;(1)&nbsp;Identify&nbsp;the&nbsp;VALUE's&nbsp;data&nbsp;type<br />
&nbsp;(2)&nbsp;Convert&nbsp;the&nbsp;VALUE&nbsp;into&nbsp;C&nbsp;data<br />
<br />
Converting&nbsp;to&nbsp;the&nbsp;wrong&nbsp;data&nbsp;type&nbsp;may&nbsp;cause&nbsp;serious&nbsp;problems.<br />
<br />
<br />
1.1&nbsp;Data-types<br />
<br />
The&nbsp;Ruby&nbsp;interpreter&nbsp;has&nbsp;the&nbsp;following&nbsp;data&nbsp;types:<br />
<br />
&nbsp;&nbsp;T_NIL&nbsp;&nbsp;nil<br />
&nbsp;&nbsp;T_OBJECT&nbsp;ordinary&nbsp;object<br />
&nbsp;&nbsp;T_CLASS&nbsp;&nbsp;class<br />
&nbsp;&nbsp;T_MODULE&nbsp;module<br />
&nbsp;&nbsp;T_FLOAT&nbsp;&nbsp;floating&nbsp;point&nbsp;number<br />
&nbsp;&nbsp;T_STRING&nbsp;string<br />
&nbsp;&nbsp;T_REGEXP&nbsp;regular&nbsp;expression<br />
&nbsp;&nbsp;T_ARRAY&nbsp;&nbsp;array<br />
&nbsp;&nbsp;T_FIXNUM&nbsp;Fixnum(31bit&nbsp;integer)<br />
&nbsp;&nbsp;T_HASH&nbsp;&nbsp;associative&nbsp;array<br />
&nbsp;&nbsp;T_STRUCT&nbsp;(Ruby)&nbsp;structure<br />
&nbsp;&nbsp;T_BIGNUM&nbsp;multi&nbsp;precision&nbsp;integer<br />
&nbsp;&nbsp;T_FILE&nbsp;&nbsp;IO<br />
&nbsp;&nbsp;T_TRUE&nbsp;&nbsp;true<br />
&nbsp;&nbsp;T_FALSE&nbsp;&nbsp;false<br />
&nbsp;&nbsp;T_DATA&nbsp;&nbsp;data<br />
&nbsp;&nbsp;T_SYMBOL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbol<br />
<br />
In&nbsp;addition,&nbsp;there&nbsp;are&nbsp;several&nbsp;other&nbsp;types&nbsp;used&nbsp;internally:<br />
<br />
&nbsp;&nbsp;T_ICLASS<br />
&nbsp;&nbsp;T_MATCH<br />
&nbsp;&nbsp;T_UNDEF<br />
&nbsp;&nbsp;T_VARMAP<br />
&nbsp;&nbsp;T_SCOPE<br />
&nbsp;&nbsp;T_NODE<br />
<br />
Most&nbsp;of&nbsp;the&nbsp;types&nbsp;are&nbsp;represented&nbsp;by&nbsp;C&nbsp;structures.<br />
<br />
1.2&nbsp;Check&nbsp;Data&nbsp;Type&nbsp;of&nbsp;the&nbsp;VALUE<br />
<br />
The&nbsp;macro&nbsp;TYPE()&nbsp;defined&nbsp;in&nbsp;ruby.h&nbsp;shows&nbsp;the&nbsp;data&nbsp;type&nbsp;of&nbsp;the&nbsp;VALUE.<br />
TYPE()&nbsp;returns&nbsp;the&nbsp;constant&nbsp;number&nbsp;T_XXXX&nbsp;described&nbsp;above.&nbsp;&nbsp;To&nbsp;handle<br />
data&nbsp;types,&nbsp;your&nbsp;code&nbsp;will&nbsp;look&nbsp;something&nbsp;like&nbsp;this:<br />
<br />
&nbsp;&nbsp;switch&nbsp;(TYPE(obj))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;T_FIXNUM:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;process&nbsp;Fixnum&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;T_STRING:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;process&nbsp;String&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;T_ARRAY:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;process&nbsp;Array&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;default:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;raise&nbsp;exception&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rb_raise(rb_eTypeError,&nbsp;&quot;not&nbsp;valid&nbsp;value&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />
&nbsp;&nbsp;}<br />
<br />
There&nbsp;is&nbsp;the&nbsp;data-type&nbsp;check&nbsp;function<br />
<br />
&nbsp;&nbsp;void&nbsp;Check_Type(VALUE&nbsp;value,&nbsp;int&nbsp;type)<br />
<br />
which&nbsp;raises&nbsp;an&nbsp;exception&nbsp;if&nbsp;the&nbsp;VALUE&nbsp;does&nbsp;not&nbsp;have&nbsp;the&nbsp;type&nbsp;specified.<br />
<br />
There&nbsp;are&nbsp;also&nbsp;faster&nbsp;check&nbsp;macros&nbsp;for&nbsp;fixnums&nbsp;and&nbsp;nil.<br />
<br />
&nbsp;&nbsp;FIXNUM_P(obj)<br />
&nbsp;&nbsp;NIL_P(obj)<br />
<br />
1.3&nbsp;Convert&nbsp;VALUE&nbsp;into&nbsp;C&nbsp;data<br />
<br />
The&nbsp;data&nbsp;for&nbsp;type&nbsp;T_NIL,&nbsp;T_FALSE,&nbsp;T_TRUE&nbsp;are&nbsp;nil,&nbsp;true,&nbsp;false<br />
respectively.&nbsp;&nbsp;They&nbsp;are&nbsp;singletons&nbsp;for&nbsp;the&nbsp;data&nbsp;type.<br />
<br />
The&nbsp;T_FIXNUM&nbsp;data&nbsp;is&nbsp;a&nbsp;31bit&nbsp;length&nbsp;fixed&nbsp;integer&nbsp;(63bit&nbsp;length&nbsp;on<br />
some&nbsp;machines),&nbsp;which&nbsp;can&nbsp;be&nbsp;convert&nbsp;to&nbsp;a&nbsp;C&nbsp;integer&nbsp;by&nbsp;using&nbsp;the<br />
FIX2INT()&nbsp;macro.&nbsp;&nbsp;There&nbsp;is&nbsp;also&nbsp;NUM2INT()&nbsp;which&nbsp;converts&nbsp;any&nbsp;Ruby<br />
numbers&nbsp;into&nbsp;C&nbsp;integers.&nbsp;&nbsp;The&nbsp;NUM2INT()&nbsp;macro&nbsp;includes&nbsp;a&nbsp;type&nbsp;check,&nbsp;so<br />
an&nbsp;exception&nbsp;will&nbsp;be&nbsp;raised&nbsp;if&nbsp;the&nbsp;conversion&nbsp;failed.&nbsp;&nbsp;NUM2DBL()&nbsp;can<br />
be&nbsp;used&nbsp;to&nbsp;retrieve&nbsp;the&nbsp;double&nbsp;float&nbsp;value&nbsp;in&nbsp;same&nbsp;way.<br />
<br />
To&nbsp;get&nbsp;char*&nbsp;from&nbsp;a&nbsp;VALUE,&nbsp;version&nbsp;1.7&nbsp;recommend&nbsp;to&nbsp;use&nbsp;new&nbsp;macros<br />
StringValue()&nbsp;and&nbsp;StringValuePtr().&nbsp;&nbsp;StringValue(var)&nbsp;replaces&nbsp;var's<br />
value&nbsp;to&nbsp;the&nbsp;result&nbsp;of&nbsp;&quot;var.to_str()&quot;.&nbsp;&nbsp;StringValuePtr(var)&nbsp;does&nbsp;same<br />
replacement&nbsp;and&nbsp;returns&nbsp;char*&nbsp;representation&nbsp;of&nbsp;var.&nbsp;&nbsp;These&nbsp;macros<br />
will&nbsp;skip&nbsp;the&nbsp;replacement&nbsp;if&nbsp;var&nbsp;is&nbsp;a&nbsp;String.&nbsp;&nbsp;Notice&nbsp;that&nbsp;the&nbsp;macros<br />
requires&nbsp;to&nbsp;take&nbsp;only&nbsp;lvalue&nbsp;as&nbsp;their&nbsp;argument,&nbsp;to&nbsp;change&nbsp;the&nbsp;value<br />
of&nbsp;var&nbsp;in&nbsp;the&nbsp;replacement.&nbsp;<br />
<br />
In&nbsp;version&nbsp;1.6&nbsp;or&nbsp;earlier,&nbsp;STR2CSTR()&nbsp;was&nbsp;used&nbsp;to&nbsp;do&nbsp;same&nbsp;thing<br />
but&nbsp;now&nbsp;it&nbsp;is&nbsp;obsoleted&nbsp;in&nbsp;version&nbsp;1.7&nbsp;because&nbsp;of&nbsp;STR2CSTR()&nbsp;has<br />
a&nbsp;risk&nbsp;of&nbsp;dangling&nbsp;pointer&nbsp;problem&nbsp;in&nbsp;to_str()&nbsp;impliclit&nbsp;conversion.<br />
<br />
Other&nbsp;data&nbsp;types&nbsp;have&nbsp;corresponding&nbsp;C&nbsp;structures,&nbsp;e.g.&nbsp;struct&nbsp;RArray<br />
for&nbsp;T_ARRAY&nbsp;etc.&nbsp;The&nbsp;VALUE&nbsp;of&nbsp;the&nbsp;type&nbsp;which&nbsp;has&nbsp;corresponding&nbsp;structure<br />
can&nbsp;be&nbsp;cast&nbsp;to&nbsp;retrieve&nbsp;the&nbsp;pointer&nbsp;to&nbsp;the&nbsp;struct.&nbsp;&nbsp;The&nbsp;casting&nbsp;macro<br />
will&nbsp;be&nbsp;of&nbsp;the&nbsp;form&nbsp;RXXXX&nbsp;for&nbsp;each&nbsp;data&nbsp;type;&nbsp;for&nbsp;instance,&nbsp;RARRAY(obj).&nbsp;<br />
See&nbsp;&quot;ruby.h&quot;.<br />
<br />
For&nbsp;example,&nbsp;`RSTRING(str)-&gt;len'&nbsp;is&nbsp;the&nbsp;way&nbsp;to&nbsp;get&nbsp;the&nbsp;size&nbsp;of&nbsp;the<br />
Ruby&nbsp;String&nbsp;object.&nbsp;&nbsp;The&nbsp;allocated&nbsp;region&nbsp;can&nbsp;be&nbsp;accessed&nbsp;by<br />
`RSTRING(str)-&gt;ptr'.&nbsp;&nbsp;For&nbsp;arrays,&nbsp;use&nbsp;`RARRAY(ary)-&gt;len'&nbsp;and<br />
`RARRAY(ary)-&gt;ptr'&nbsp;respectively.<br />
<br />
Notice:&nbsp;Do&nbsp;not&nbsp;change&nbsp;the&nbsp;value&nbsp;of&nbsp;the&nbsp;structure&nbsp;directly,&nbsp;unless&nbsp;you<br />
are&nbsp;responsible&nbsp;for&nbsp;the&nbsp;result.&nbsp;&nbsp;This&nbsp;ends&nbsp;up&nbsp;being&nbsp;the&nbsp;cause&nbsp;of&nbsp;interesting<br />
bugs.<br />
<br />
1.4&nbsp;Convert&nbsp;C&nbsp;data&nbsp;into&nbsp;VALUE<br />
<br />
To&nbsp;convert&nbsp;C&nbsp;data&nbsp;to&nbsp;Ruby&nbsp;values:<br />
<br />
&nbsp;&nbsp;*&nbsp;FIXNUM<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;left&nbsp;shift&nbsp;1&nbsp;bit,&nbsp;and&nbsp;turn&nbsp;on&nbsp;LSB.<br />
<br />
&nbsp;&nbsp;*&nbsp;Other&nbsp;pointer&nbsp;values<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;cast&nbsp;to&nbsp;VALUE.<br />
<br />
You&nbsp;can&nbsp;determine&nbsp;whether&nbsp;a&nbsp;VALUE&nbsp;is&nbsp;pointer&nbsp;or&nbsp;not&nbsp;by&nbsp;checking&nbsp;its&nbsp;LSB.&nbsp;&nbsp;<br />
<br />
Notice&nbsp;Ruby&nbsp;does&nbsp;not&nbsp;allow&nbsp;arbitrary&nbsp;pointer&nbsp;values&nbsp;to&nbsp;be&nbsp;a&nbsp;VALUE.&nbsp;&nbsp;They<br />
should&nbsp;be&nbsp;pointers&nbsp;to&nbsp;the&nbsp;structures&nbsp;which&nbsp;Ruby&nbsp;knows&nbsp;about.&nbsp;&nbsp;The&nbsp;known<br />
structures&nbsp;are&nbsp;defined&nbsp;in&nbsp;&lt;ruby.h&gt;.<br />
<br />
To&nbsp;convert&nbsp;C&nbsp;numbers&nbsp;to&nbsp;Ruby&nbsp;values,&nbsp;use&nbsp;these&nbsp;macros.<br />
<br />
&nbsp;&nbsp;INT2FIX()&nbsp;&nbsp;for&nbsp;integers&nbsp;within&nbsp;31bits.<br />
&nbsp;&nbsp;INT2NUM()&nbsp;&nbsp;for&nbsp;arbitrary&nbsp;sized&nbsp;integer.<br />
<br />
INT2NUM()&nbsp;converts&nbsp;an&nbsp;integer&nbsp;into&nbsp;a&nbsp;Bignum&nbsp;if&nbsp;it&nbsp;is&nbsp;out&nbsp;of&nbsp;the&nbsp;FIXNUM<br />
range,&nbsp;but&nbsp;is&nbsp;a&nbsp;bit&nbsp;slower.<br />
<br />
1.5&nbsp;Manipulating&nbsp;Ruby&nbsp;data<br />
<br />
As&nbsp;I&nbsp;already&nbsp;mentioned,&nbsp;it&nbsp;is&nbsp;not&nbsp;recommended&nbsp;to&nbsp;modify&nbsp;an&nbsp;object's&nbsp;internal<br />
structure.&nbsp;&nbsp;To&nbsp;manipulate&nbsp;objects,&nbsp;use&nbsp;the&nbsp;functions&nbsp;supplied&nbsp;by&nbsp;the&nbsp;Ruby<br />
interpreter.&nbsp;Some&nbsp;(not&nbsp;all)&nbsp;of&nbsp;the&nbsp;useful&nbsp;functions&nbsp;are&nbsp;listed&nbsp;below:<br />
<br />
&nbsp;String&nbsp;functions<br />
<br />
&nbsp;&nbsp;rb_str_new(const&nbsp;char&nbsp;*ptr,&nbsp;long&nbsp;len)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;Creates&nbsp;a&nbsp;new&nbsp;Ruby&nbsp;string.<br />
<br />
&nbsp;&nbsp;rb_str_new2(const&nbsp;char&nbsp;*ptr)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;Creates&nbsp;a&nbsp;new&nbsp;Ruby&nbsp;string&nbsp;from&nbsp;a&nbsp;C&nbsp;string.&nbsp;&nbsp;This&nbsp;is&nbsp;equivalent&nbsp;to<br />
&nbsp;&nbsp;&nbsp;&nbsp;rb_str_new(ptr,&nbsp;strlen(ptr)).<br />
<br />
&nbsp;&nbsp;rb_tainted_str_new(const&nbsp;char&nbsp;*ptr,&nbsp;long&nbsp;len)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;Creates&nbsp;a&nbsp;new&nbsp;tainted&nbsp;Ruby&nbsp;string.&nbsp;&nbsp;Strings&nbsp;from&nbsp;external&nbsp;data<br />
&nbsp;&nbsp;&nbsp;&nbsp;sources&nbsp;should&nbsp;be&nbsp;tainted.<br />
<br />
&nbsp;&nbsp;rb_tainted_str_new2(const&nbsp;char&nbsp;*ptr)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;Creates&nbsp;a&nbsp;new&nbsp;tainted&nbsp;Ruby&nbsp;string&nbsp;from&nbsp;a&nbsp;C&nbsp;string.<br />
<br />
&nbsp;&nbsp;rb_str_cat(VALUE&nbsp;str,&nbsp;const&nbsp;char&nbsp;*ptr,&nbsp;long&nbsp;len)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;Appends&nbsp;len&nbsp;bytes&nbsp;of&nbsp;data&nbsp;from&nbsp;ptr&nbsp;to&nbsp;the&nbsp;Ruby&nbsp;string.<br />
<br />
&nbsp;Array&nbsp;functions<br />
<br />
&nbsp;&nbsp;rb_ary_new()<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;Creates&nbsp;an&nbsp;array&nbsp;with&nbsp;no&nbsp;elements.<br />
<br />
&nbsp;&nbsp;rb_ary_new2(long&nbsp;len)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;Creates&nbsp;an&nbsp;array&nbsp;with&nbsp;no&nbsp;elements,&nbsp;allocating&nbsp;internal&nbsp;buffer<br />
&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;len&nbsp;elements.<br />
<br />
&nbsp;&nbsp;rb_ary_new3(long&nbsp;n,&nbsp;...)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;Creates&nbsp;an&nbsp;n-element&nbsp;array&nbsp;from&nbsp;the&nbsp;arguments.<br />
<br />
&nbsp;&nbsp;rb_ary_new4(long&nbsp;n,&nbsp;VALUE&nbsp;*elts)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;Creates&nbsp;an&nbsp;n-element&nbsp;array&nbsp;from&nbsp;a&nbsp;C&nbsp;array.<br />
<br />
&nbsp;&nbsp;rb_ary_push(VALUE&nbsp;ary,&nbsp;VALUE&nbsp;val)<br />
&nbsp;&nbsp;rb_ary_pop(VALUE&nbsp;ary)<br />
&nbsp;&nbsp;rb_ary_shift(VALUE&nbsp;ary)<br />
&nbsp;&nbsp;rb_ary_unshift(VALUE&nbsp;ary,&nbsp;VALUE&nbsp;val)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;Array&nbsp;operations.&nbsp;&nbsp;The&nbsp;first&nbsp;argument&nbsp;to&nbsp;each&nbsp;functions&nbsp;must&nbsp;be&nbsp;an&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;array.&nbsp;&nbsp;They&nbsp;may&nbsp;dump&nbsp;core&nbsp;if&nbsp;other&nbsp;types&nbsp;given.<br />
<br />
2.&nbsp;Extending&nbsp;Ruby&nbsp;with&nbsp;C<br />
<br />
2.1&nbsp;Addding&nbsp;new&nbsp;features&nbsp;to&nbsp;Ruby<br />
<br />
You&nbsp;can&nbsp;add&nbsp;new&nbsp;features&nbsp;(classes,&nbsp;methods,&nbsp;etc.)&nbsp;to&nbsp;the&nbsp;Ruby<br />
interpreter.&nbsp;&nbsp;Ruby&nbsp;provides&nbsp;APIs&nbsp;for&nbsp;defining&nbsp;the&nbsp;following&nbsp;things:<br />
<br />
&nbsp;*&nbsp;Classes,&nbsp;Modules<br />
&nbsp;*&nbsp;Methods,&nbsp;Singleton&nbsp;Methods<br />
&nbsp;*&nbsp;Constants<br />
<br />
2.1.1&nbsp;Class/module&nbsp;definition<br />
<br />
To&nbsp;define&nbsp;a&nbsp;class&nbsp;or&nbsp;module,&nbsp;use&nbsp;the&nbsp;functions&nbsp;below:<br />
<br />
&nbsp;&nbsp;VALUE&nbsp;rb_define_class(const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;super)<br />
&nbsp;&nbsp;VALUE&nbsp;rb_define_module(const&nbsp;char&nbsp;*name)<br />
<br />
These&nbsp;functions&nbsp;return&nbsp;the&nbsp;newly&nbsp;created&nbsp;class&nbsp;or&nbsp;module.&nbsp;&nbsp;You&nbsp;may<br />
want&nbsp;to&nbsp;save&nbsp;this&nbsp;reference&nbsp;into&nbsp;a&nbsp;variable&nbsp;to&nbsp;use&nbsp;later.<br />
<br />
To&nbsp;define&nbsp;nested&nbsp;classes&nbsp;or&nbsp;modules,&nbsp;use&nbsp;the&nbsp;functions&nbsp;below:<br />
<br />
&nbsp;&nbsp;VALUE&nbsp;rb_define_class_under(VALUE&nbsp;outer,&nbsp;const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;super)<br />
&nbsp;&nbsp;VALUE&nbsp;rb_define_module_under(VALUE&nbsp;outer,&nbsp;const&nbsp;char&nbsp;*name)<br />
<br />
2.1.2&nbsp;Method/singleton&nbsp;method&nbsp;definition<br />
<br />
To&nbsp;define&nbsp;methods&nbsp;or&nbsp;singleton&nbsp;methods,&nbsp;use&nbsp;these&nbsp;functions:<br />
<br />
&nbsp;&nbsp;void&nbsp;rb_define_method(VALUE&nbsp;klass,&nbsp;const&nbsp;char&nbsp;*name,&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VALUE&nbsp;(*func)(),&nbsp;int&nbsp;argc)<br />
<br />
&nbsp;&nbsp;void&nbsp;rb_define_singleton_method(VALUE&nbsp;object,&nbsp;const&nbsp;char&nbsp;*name,&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VALUE&nbsp;(*func)(),&nbsp;int&nbsp;argc)<br />
<br />
The&nbsp;`argc'&nbsp;represents&nbsp;the&nbsp;number&nbsp;of&nbsp;the&nbsp;arguments&nbsp;to&nbsp;the&nbsp;C&nbsp;function,<br />
which&nbsp;must&nbsp;be&nbsp;less&nbsp;than&nbsp;17.&nbsp;&nbsp;But&nbsp;I&nbsp;believe&nbsp;you&nbsp;don't&nbsp;need&nbsp;that&nbsp;much.&nbsp;:-)<br />
<br />
If&nbsp;`argc'&nbsp;is&nbsp;negative,&nbsp;it&nbsp;specifies&nbsp;the&nbsp;calling&nbsp;sequence,&nbsp;not&nbsp;number&nbsp;of<br />
the&nbsp;arguments.&nbsp;&nbsp;<br />
<br />
If&nbsp;argc&nbsp;is&nbsp;-1,&nbsp;the&nbsp;function&nbsp;will&nbsp;be&nbsp;called&nbsp;as:<br />
<br />
&nbsp;&nbsp;VALUE&nbsp;func(int&nbsp;argc,&nbsp;VALUE&nbsp;*argv,&nbsp;VALUE&nbsp;obj)<br />
<br />
where&nbsp;argc&nbsp;is&nbsp;the&nbsp;actual&nbsp;number&nbsp;of&nbsp;arguments,&nbsp;argv&nbsp;is&nbsp;the&nbsp;C&nbsp;array&nbsp;of<br />
the&nbsp;arguments,&nbsp;and&nbsp;obj&nbsp;is&nbsp;the&nbsp;receiver.<br />
<br />
If&nbsp;argc&nbsp;is&nbsp;-2,&nbsp;the&nbsp;arguments&nbsp;are&nbsp;passed&nbsp;in&nbsp;a&nbsp;Ruby&nbsp;array.&nbsp;The&nbsp;function<br />
will&nbsp;be&nbsp;called&nbsp;like:<br />
<br />
&nbsp;&nbsp;VALUE&nbsp;func(VALUE&nbsp;obj,&nbsp;VALUE&nbsp;args)<br />
<br />
where&nbsp;obj&nbsp;is&nbsp;the&nbsp;receiver,&nbsp;and&nbsp;args&nbsp;is&nbsp;the&nbsp;Ruby&nbsp;array&nbsp;containing<br />
actual&nbsp;arguments.<br />
<br />
There&nbsp;are&nbsp;two&nbsp;more&nbsp;functions&nbsp;to&nbsp;define&nbsp;methods.&nbsp;&nbsp;One&nbsp;is&nbsp;to&nbsp;define<br />
private&nbsp;methods:<br />
<br />
&nbsp;&nbsp;void&nbsp;rb_define_private_method(VALUE&nbsp;klass,&nbsp;const&nbsp;char&nbsp;*name,&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VALUE&nbsp;(*func)(),&nbsp;int&nbsp;argc)<br />
<br />
The&nbsp;other&nbsp;is&nbsp;to&nbsp;define&nbsp;module&nbsp;functions,&nbsp;which&nbsp;are&nbsp;private&nbsp;AND&nbsp;singleton<br />
methods&nbsp;of&nbsp;the&nbsp;module.&nbsp;&nbsp;For&nbsp;example,&nbsp;sqrt&nbsp;is&nbsp;the&nbsp;module&nbsp;function<br />
defined&nbsp;in&nbsp;Math&nbsp;module.&nbsp;&nbsp;It&nbsp;can&nbsp;be&nbsp;call&nbsp;in&nbsp;the&nbsp;form&nbsp;like:<br />
<br />
&nbsp;&nbsp;Math.sqrt(4)<br />
<br />
or<br />
<br />
&nbsp;&nbsp;include&nbsp;Math<br />
&nbsp;&nbsp;sqrt(4)<br />
<br />
To&nbsp;define&nbsp;module&nbsp;functions,&nbsp;use:<br />
<br />
&nbsp;&nbsp;void&nbsp;rb_define_module_function(VALUE&nbsp;module,&nbsp;const&nbsp;char&nbsp;*name,&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VALUE&nbsp;(*func)(),&nbsp;int&nbsp;argc)<br />
<br />
Oh,&nbsp;in&nbsp;addition,&nbsp;function-like&nbsp;methods,&nbsp;which&nbsp;are&nbsp;private&nbsp;methods&nbsp;defined<br />
in&nbsp;the&nbsp;Kernel&nbsp;module,&nbsp;can&nbsp;be&nbsp;defined&nbsp;using:<br />
<br />
&nbsp;&nbsp;void&nbsp;rb_define_global_function(const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;(*func)(),&nbsp;int&nbsp;argc)<br />
<br />
To&nbsp;define&nbsp;alias&nbsp;to&nbsp;the&nbsp;method,<br />
<br />
&nbsp;&nbsp;void&nbsp;rb_define_alias(VALUE&nbsp;module,&nbsp;const&nbsp;char*&nbsp;new,&nbsp;const&nbsp;char*&nbsp;old);<br />
<br />
2.1.3&nbsp;Constant&nbsp;definition<br />
<br />
We&nbsp;have&nbsp;2&nbsp;functions&nbsp;to&nbsp;define&nbsp;constants:<br />
<br />
&nbsp;&nbsp;void&nbsp;rb_define_const(VALUE&nbsp;klass,&nbsp;const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;val)<br />
&nbsp;&nbsp;void&nbsp;rb_define_global_const(const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;val)<br />
<br />
The&nbsp;former&nbsp;is&nbsp;to&nbsp;define&nbsp;a&nbsp;constant&nbsp;under&nbsp;specified&nbsp;class/module.&nbsp;&nbsp;The<br />
latter&nbsp;is&nbsp;to&nbsp;define&nbsp;a&nbsp;global&nbsp;constant.<br />
<br />
2.2&nbsp;Use&nbsp;Ruby&nbsp;features&nbsp;from&nbsp;C<br />
<br />
There&nbsp;are&nbsp;several&nbsp;ways&nbsp;to&nbsp;invoke&nbsp;Ruby's&nbsp;features&nbsp;from&nbsp;C&nbsp;code.<br />
<br />
2.2.1&nbsp;Evaluate&nbsp;Ruby&nbsp;Programs&nbsp;in&nbsp;a&nbsp;String<br />
<br />
The&nbsp;easiest&nbsp;way&nbsp;to&nbsp;use&nbsp;Ruby's&nbsp;functionality&nbsp;from&nbsp;a&nbsp;C&nbsp;program&nbsp;is&nbsp;to<br />
evaluate&nbsp;the&nbsp;string&nbsp;as&nbsp;Ruby&nbsp;program.&nbsp;&nbsp;This&nbsp;function&nbsp;will&nbsp;do&nbsp;the&nbsp;job.<br />
<br />
&nbsp;&nbsp;VALUE&nbsp;rb_eval_string(const&nbsp;char&nbsp;*str)<br />
<br />
Evaluation&nbsp;is&nbsp;done&nbsp;under&nbsp;the&nbsp;current&nbsp;context,&nbsp;thus&nbsp;current&nbsp;local&nbsp;variables<br />
of&nbsp;the&nbsp;innermost&nbsp;method&nbsp;(which&nbsp;is&nbsp;defined&nbsp;by&nbsp;Ruby)&nbsp;can&nbsp;be&nbsp;accessed.<br />
<br />
2.2.2&nbsp;ID&nbsp;or&nbsp;Symbol<br />
<br />
You&nbsp;can&nbsp;invoke&nbsp;methods&nbsp;directly,&nbsp;without&nbsp;parsing&nbsp;the&nbsp;string.&nbsp;&nbsp;First&nbsp;I<br />
need&nbsp;to&nbsp;explain&nbsp;about&nbsp;symbols&nbsp;(whose&nbsp;data&nbsp;type&nbsp;is&nbsp;ID).&nbsp;&nbsp;ID&nbsp;is&nbsp;the<br />
integer&nbsp;number&nbsp;to&nbsp;represent&nbsp;Ruby's&nbsp;identifiers&nbsp;such&nbsp;as&nbsp;variable&nbsp;names.<br />
It&nbsp;can&nbsp;be&nbsp;accessed&nbsp;from&nbsp;Ruby&nbsp;in&nbsp;the&nbsp;form:<br />
<br />
&nbsp;:Identifier<br />
<br />
You&nbsp;can&nbsp;get&nbsp;the&nbsp;symbol&nbsp;value&nbsp;from&nbsp;a&nbsp;string&nbsp;within&nbsp;C&nbsp;code&nbsp;by&nbsp;using<br />
<br />
&nbsp;&nbsp;rb_intern(const&nbsp;char&nbsp;*name)<br />
<br />
2.2.3&nbsp;Invoke&nbsp;Ruby&nbsp;method&nbsp;from&nbsp;C<br />
<br />
To&nbsp;invoke&nbsp;methods&nbsp;directly,&nbsp;you&nbsp;can&nbsp;use&nbsp;the&nbsp;function&nbsp;below<br />
<br />
&nbsp;&nbsp;VALUE&nbsp;rb_funcall(VALUE&nbsp;recv,&nbsp;ID&nbsp;mid,&nbsp;int&nbsp;argc,&nbsp;...)<br />
<br />
This&nbsp;function&nbsp;invokes&nbsp;a&nbsp;method&nbsp;on&nbsp;the&nbsp;recv,&nbsp;with&nbsp;the&nbsp;method&nbsp;name<br />
specified&nbsp;by&nbsp;the&nbsp;symbol&nbsp;mid.<br />
<br />
2.2.4&nbsp;Accessing&nbsp;the&nbsp;variables&nbsp;and&nbsp;constants<br />
<br />
You&nbsp;can&nbsp;access&nbsp;class&nbsp;variables&nbsp;and&nbsp;instance&nbsp;variables&nbsp;using&nbsp;access<br />
functions.&nbsp;&nbsp;Also,&nbsp;global&nbsp;variables&nbsp;can&nbsp;be&nbsp;shared&nbsp;between&nbsp;both&nbsp;environments.<br />
There's&nbsp;no&nbsp;way&nbsp;to&nbsp;access&nbsp;Ruby's&nbsp;local&nbsp;variables.<br />
<br />
The&nbsp;functions&nbsp;to&nbsp;access/modify&nbsp;instance&nbsp;variables&nbsp;are&nbsp;below:<br />
<br />
&nbsp;&nbsp;VALUE&nbsp;rb_ivar_get(VALUE&nbsp;obj,&nbsp;ID&nbsp;id)<br />
&nbsp;&nbsp;VALUE&nbsp;rb_ivar_set(VALUE&nbsp;obj,&nbsp;ID&nbsp;id,&nbsp;VALUE&nbsp;val)<br />
<br />
id&nbsp;must&nbsp;be&nbsp;the&nbsp;symbol,&nbsp;which&nbsp;can&nbsp;be&nbsp;retrieved&nbsp;by&nbsp;rb_intern().<br />
<br />
To&nbsp;access&nbsp;the&nbsp;constants&nbsp;of&nbsp;the&nbsp;class/module:<br />
<br />
&nbsp;&nbsp;VALUE&nbsp;rb_const_get(VALUE&nbsp;obj,&nbsp;ID&nbsp;id)<br />
<br />
See&nbsp;2.1.3&nbsp;for&nbsp;defining&nbsp;new&nbsp;constant.<br />
<br />
3.&nbsp;Information&nbsp;sharing&nbsp;between&nbsp;Ruby&nbsp;and&nbsp;C<br />
<br />
3.1&nbsp;Ruby&nbsp;constants&nbsp;that&nbsp;C&nbsp;can&nbsp;be&nbsp;accessed&nbsp;from&nbsp;C<br />
<br />
The&nbsp;following&nbsp;Ruby&nbsp;constants&nbsp;can&nbsp;be&nbsp;referred&nbsp;from&nbsp;C.<br />
<br />
&nbsp;&nbsp;Qtrue<br />
&nbsp;&nbsp;Qfalse<br />
<br />
Boolean&nbsp;values.&nbsp;&nbsp;Qfalse&nbsp;is&nbsp;false&nbsp;in&nbsp;C&nbsp;also&nbsp;(i.e.&nbsp;0).<br />
<br />
&nbsp;&nbsp;Qnil<br />
<br />
Ruby&nbsp;nil&nbsp;in&nbsp;C&nbsp;scope.<br />
<br />
3.2&nbsp;Global&nbsp;variables&nbsp;shared&nbsp;between&nbsp;C&nbsp;and&nbsp;Ruby<br />
<br />
Information&nbsp;can&nbsp;be&nbsp;shared&nbsp;between&nbsp;the&nbsp;two&nbsp;environments&nbsp;using&nbsp;shared&nbsp;global<br />
variables.&nbsp;&nbsp;To&nbsp;define&nbsp;them,&nbsp;you&nbsp;can&nbsp;use&nbsp;functions&nbsp;listed&nbsp;below:<br />
<br />
&nbsp;&nbsp;void&nbsp;rb_define_variable(const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;*var)<br />
<br />
This&nbsp;function&nbsp;defines&nbsp;the&nbsp;variable&nbsp;which&nbsp;is&nbsp;shared&nbsp;by&nbsp;both&nbsp;environments.<br />
The&nbsp;value&nbsp;of&nbsp;the&nbsp;global&nbsp;variable&nbsp;pointed&nbsp;to&nbsp;by&nbsp;`var'&nbsp;can&nbsp;be&nbsp;accessed<br />
through&nbsp;Ruby's&nbsp;global&nbsp;variable&nbsp;named&nbsp;`name'.<br />
<br />
You&nbsp;can&nbsp;define&nbsp;read-only&nbsp;(from&nbsp;Ruby,&nbsp;of&nbsp;course)&nbsp;variables&nbsp;using&nbsp;the<br />
function&nbsp;below.<br />
<br />
&nbsp;&nbsp;void&nbsp;rb_define_readonly_variable(const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;*var)<br />
<br />
You&nbsp;can&nbsp;defined&nbsp;hooked&nbsp;variables.&nbsp;&nbsp;The&nbsp;accessor&nbsp;functions&nbsp;(getter&nbsp;and<br />
setter)&nbsp;are&nbsp;called&nbsp;on&nbsp;access&nbsp;to&nbsp;the&nbsp;hooked&nbsp;variables.<br />
<br />
&nbsp;&nbsp;void&nbsp;rb_define_hooked_variable(constchar&nbsp;*name,&nbsp;VALUE&nbsp;*var,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VALUE&nbsp;(*getter)(),&nbsp;void&nbsp;(*setter)())<br />
<br />
If&nbsp;you&nbsp;need&nbsp;to&nbsp;supply&nbsp;either&nbsp;setter&nbsp;or&nbsp;getter,&nbsp;just&nbsp;supply&nbsp;0&nbsp;for&nbsp;the<br />
hook&nbsp;you&nbsp;don't&nbsp;need.&nbsp;&nbsp;If&nbsp;both&nbsp;hooks&nbsp;are&nbsp;0,&nbsp;rb_define_hooked_variable()<br />
works&nbsp;just&nbsp;like&nbsp;rb_define_variable().<br />
<br />
&nbsp;&nbsp;void&nbsp;rb_define_virtual_variable(const&nbsp;char&nbsp;*name,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VALUE&nbsp;(*getter)(),&nbsp;void&nbsp;(*setter)())<br />
<br />
This&nbsp;function&nbsp;defines&nbsp;a&nbsp;Ruby&nbsp;global&nbsp;variable&nbsp;without&nbsp;a&nbsp;corresponding&nbsp;C<br />
variable.&nbsp;&nbsp;The&nbsp;value&nbsp;of&nbsp;the&nbsp;variable&nbsp;will&nbsp;be&nbsp;set/get&nbsp;only&nbsp;by&nbsp;hooks.<br />
<br />
The&nbsp;prototypes&nbsp;of&nbsp;the&nbsp;getter&nbsp;and&nbsp;setter&nbsp;functions&nbsp;are&nbsp;as&nbsp;follows:<br />
<br />
&nbsp;&nbsp;(*getter)(ID&nbsp;id,&nbsp;void&nbsp;*data,&nbsp;struct&nbsp;global_entry*&nbsp;entry);<br />
&nbsp;&nbsp;(*setter)(VALUE&nbsp;val,&nbsp;ID&nbsp;id,&nbsp;void&nbsp;*data,&nbsp;struct&nbsp;global_entry*&nbsp;entry);<br />
<br />
3.3&nbsp;Encapsulate&nbsp;C&nbsp;data&nbsp;into&nbsp;Ruby&nbsp;object<br />
<br />
To&nbsp;wrap&nbsp;and&nbsp;objectify&nbsp;a&nbsp;C&nbsp;pointer&nbsp;as&nbsp;a&nbsp;Ruby&nbsp;object&nbsp;(so&nbsp;called<br />
DATA),&nbsp;use&nbsp;Data_Wrap_Struct().<br />
<br />
&nbsp;&nbsp;Data_Wrap_Struct(klass,&nbsp;mark,&nbsp;free,&nbsp;ptr)<br />
<br />
Data_Wrap_Struct()&nbsp;returns&nbsp;a&nbsp;created&nbsp;DATA&nbsp;object.&nbsp;&nbsp;The&nbsp;klass&nbsp;argument<br />
is&nbsp;the&nbsp;class&nbsp;for&nbsp;the&nbsp;DATA&nbsp;object.&nbsp;&nbsp;The&nbsp;mark&nbsp;argument&nbsp;is&nbsp;the&nbsp;function<br />
to&nbsp;mark&nbsp;Ruby&nbsp;objects&nbsp;pointed&nbsp;by&nbsp;this&nbsp;data.&nbsp;&nbsp;The&nbsp;free&nbsp;argument&nbsp;is&nbsp;the<br />
function&nbsp;to&nbsp;free&nbsp;the&nbsp;pointer&nbsp;allocation.&nbsp;&nbsp;If&nbsp;this&nbsp;is&nbsp;-1,&nbsp;the&nbsp;pointer<br />
will&nbsp;be&nbsp;just&nbsp;freed.&nbsp;&nbsp;The&nbsp;functions&nbsp;mark&nbsp;and&nbsp;free&nbsp;will&nbsp;be&nbsp;called&nbsp;from<br />
garbage&nbsp;collector.<br />
<br />
You&nbsp;can&nbsp;allocate&nbsp;and&nbsp;wrap&nbsp;the&nbsp;structure&nbsp;in&nbsp;one&nbsp;step.<br />
<br />
&nbsp;&nbsp;Data_Make_Struct(klass,&nbsp;type,&nbsp;mark,&nbsp;free,&nbsp;sval)<br />
<br />
This&nbsp;macro&nbsp;returns&nbsp;an&nbsp;allocated&nbsp;Data&nbsp;object,&nbsp;wrapping&nbsp;the&nbsp;pointer&nbsp;to<br />
the&nbsp;structure,&nbsp;which&nbsp;is&nbsp;also&nbsp;allocated.&nbsp;&nbsp;This&nbsp;macro&nbsp;works&nbsp;like:<br />
<br />
&nbsp;&nbsp;(sval&nbsp;=&nbsp;ALLOC(type),&nbsp;Data_Wrap_Struct(klass,&nbsp;mark,&nbsp;free,&nbsp;sval))<br />
<br />
Arguments&nbsp;klass,&nbsp;mark,&nbsp;and&nbsp;free&nbsp;work&nbsp;like&nbsp;their&nbsp;counterparts&nbsp;in<br />
Data_Wrap_Struct().&nbsp;&nbsp;A&nbsp;pointer&nbsp;to&nbsp;the&nbsp;allocated&nbsp;structure&nbsp;will&nbsp;be<br />
assigned&nbsp;to&nbsp;sval,&nbsp;which&nbsp;should&nbsp;be&nbsp;a&nbsp;pointer&nbsp;of&nbsp;the&nbsp;type&nbsp;specified.<br />
<br />
To&nbsp;retrieve&nbsp;the&nbsp;C&nbsp;pointer&nbsp;from&nbsp;the&nbsp;Data&nbsp;object,&nbsp;use&nbsp;the&nbsp;macro<br />
Data_Get_Struct().<br />
<br />
&nbsp;&nbsp;Data_Get_Struct(obj,&nbsp;type,&nbsp;sval)<br />
<br />
A&nbsp;pointer&nbsp;to&nbsp;the&nbsp;structure&nbsp;will&nbsp;be&nbsp;assigned&nbsp;to&nbsp;the&nbsp;variable&nbsp;sval.<br />
<br />
See&nbsp;the&nbsp;example&nbsp;below&nbsp;for&nbsp;details.&nbsp;<br />
<br />
4.&nbsp;Example&nbsp;-&nbsp;Creating&nbsp;dbm&nbsp;extension<br />
<br />
OK,&nbsp;here's&nbsp;the&nbsp;example&nbsp;of&nbsp;making&nbsp;an&nbsp;extension&nbsp;library.&nbsp;&nbsp;This&nbsp;is&nbsp;the<br />
extension&nbsp;to&nbsp;access&nbsp;DBMs.&nbsp;&nbsp;The&nbsp;full&nbsp;source&nbsp;is&nbsp;included&nbsp;in&nbsp;the&nbsp;ext/<br />
directory&nbsp;in&nbsp;the&nbsp;Ruby's&nbsp;source&nbsp;tree.<br />
<br />
(1)&nbsp;make&nbsp;the&nbsp;directory<br />
<br />
&nbsp;&nbsp;%&nbsp;mkdir&nbsp;ext/dbm<br />
<br />
Make&nbsp;a&nbsp;directory&nbsp;for&nbsp;the&nbsp;extension&nbsp;library&nbsp;under&nbsp;ext&nbsp;directory.<br />
<br />
(2)&nbsp;create&nbsp;MANIFEST&nbsp;file<br />
<br />
&nbsp;&nbsp;%&nbsp;cd&nbsp;ext/dbm<br />
&nbsp;&nbsp;%&nbsp;touch&nbsp;MANIFEST<br />
<br />
There&nbsp;should&nbsp;be&nbsp;MANIFEST&nbsp;file&nbsp;in&nbsp;the&nbsp;directory&nbsp;for&nbsp;the&nbsp;extension<br />
library.&nbsp;&nbsp;Make&nbsp;an&nbsp;empty&nbsp;file&nbsp;for&nbsp;now.<br />
<br />
(3)&nbsp;design&nbsp;the&nbsp;library<br />
<br />
You&nbsp;need&nbsp;to&nbsp;design&nbsp;the&nbsp;library&nbsp;features,&nbsp;before&nbsp;making&nbsp;it.<br />
<br />
(4)&nbsp;write&nbsp;C&nbsp;code.<br />
<br />
You&nbsp;need&nbsp;to&nbsp;write&nbsp;C&nbsp;code&nbsp;for&nbsp;your&nbsp;extension&nbsp;library.&nbsp;&nbsp;If&nbsp;your&nbsp;library<br />
has&nbsp;only&nbsp;one&nbsp;source&nbsp;file,&nbsp;choosing&nbsp;``LIBRARY.c''&nbsp;as&nbsp;a&nbsp;file&nbsp;name&nbsp;is<br />
preferred.&nbsp;&nbsp;On&nbsp;the&nbsp;other&nbsp;hand,&nbsp;in&nbsp;case&nbsp;your&nbsp;library&nbsp;has&nbsp;multiple&nbsp;source<br />
files,&nbsp;avoid&nbsp;choosing&nbsp;``LIBRARY.c''&nbsp;for&nbsp;a&nbsp;file&nbsp;name.&nbsp;&nbsp;It&nbsp;may&nbsp;conflict<br />
with&nbsp;an&nbsp;intermediate&nbsp;file&nbsp;``LIBRARY.o''&nbsp;on&nbsp;some&nbsp;platforms.<br />
<br />
Ruby&nbsp;will&nbsp;execute&nbsp;the&nbsp;initializing&nbsp;function&nbsp;named&nbsp;``Init_LIBRARY''&nbsp;in<br />
the&nbsp;library.&nbsp;&nbsp;For&nbsp;example,&nbsp;``Init_dbm()''&nbsp;will&nbsp;be&nbsp;executed&nbsp;when&nbsp;loading<br />
the&nbsp;library.<br />
<br />
Here's&nbsp;the&nbsp;example&nbsp;of&nbsp;an&nbsp;initializing&nbsp;function.<br />
<br />
--<br />
Init_dbm()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;define&nbsp;DBM&nbsp;class&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;cDBM&nbsp;=&nbsp;rb_define_class(&quot;DBM&quot;,&nbsp;rb_cObject);<br />
&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;DBM&nbsp;includes&nbsp;Enumerate&nbsp;module&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;rb_include_module(cDBM,&nbsp;rb_mEnumerable);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;DBM&nbsp;has&nbsp;class&nbsp;method&nbsp;open():&nbsp;arguments&nbsp;are&nbsp;received&nbsp;as&nbsp;C&nbsp;array&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;rb_define_singleton_method(cDBM,&nbsp;&quot;open&quot;,&nbsp;fdbm_s_open,&nbsp;-1);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;DBM&nbsp;instance&nbsp;method&nbsp;close():&nbsp;no&nbsp;args&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;rb_define_method(cDBM,&nbsp;&quot;close&quot;,&nbsp;fdbm_close,&nbsp;0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;DBM&nbsp;instance&nbsp;method&nbsp;[]:&nbsp;1&nbsp;argument&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;rb_define_method(cDBM,&nbsp;&quot;[]&quot;,&nbsp;fdbm_fetch,&nbsp;1);<br />
&nbsp;&nbsp;&nbsp;:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;ID&nbsp;for&nbsp;a&nbsp;instance&nbsp;variable&nbsp;to&nbsp;store&nbsp;DBM&nbsp;data&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;id_dbm&nbsp;=&nbsp;rb_intern(&quot;dbm&quot;);<br />
}<br />
--<br />
<br />
The&nbsp;dbm&nbsp;extension&nbsp;wraps&nbsp;the&nbsp;dbm&nbsp;struct&nbsp;in&nbsp;the&nbsp;C&nbsp;environment&nbsp;using&nbsp;<br />
Data_Make_Struct.<br />
<br />
--<br />
struct&nbsp;dbmdata&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;di_size;<br />
&nbsp;&nbsp;&nbsp;&nbsp;DBM&nbsp;*di_dbm;<br />
};<br />
<br />
<br />
obj&nbsp;=&nbsp;Data_Make_Struct(klass,&nbsp;struct&nbsp;dbmdata,&nbsp;0,&nbsp;free_dbm,&nbsp;dbmp);<br />
--<br />
<br />
This&nbsp;code&nbsp;wraps&nbsp;the&nbsp;dbmdata&nbsp;structure&nbsp;into&nbsp;a&nbsp;Ruby&nbsp;object.&nbsp;&nbsp;We&nbsp;avoid&nbsp;wrapping<br />
DBM*&nbsp;directly,&nbsp;because&nbsp;we&nbsp;want&nbsp;to&nbsp;cache&nbsp;size&nbsp;information.<br />
<br />
To&nbsp;retrieve&nbsp;the&nbsp;dbmdata&nbsp;structure&nbsp;from&nbsp;a&nbsp;Ruby&nbsp;object,&nbsp;we&nbsp;define&nbsp;the<br />
following&nbsp;macro:<br />
<br />
--<br />
#define&nbsp;GetDBM(obj,&nbsp;dbmp)&nbsp;{\<br />
&nbsp;&nbsp;&nbsp;&nbsp;Data_Get_Struct(obj,&nbsp;struct&nbsp;dbmdata,&nbsp;dbmp);\<br />
&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(dbmp-&gt;di_dbm&nbsp;==&nbsp;0)&nbsp;closed_dbm();\<br />
}<br />
--<br />
<br />
This&nbsp;sort&nbsp;of&nbsp;complicated&nbsp;macro&nbsp;does&nbsp;the&nbsp;retrieving&nbsp;and&nbsp;close&nbsp;checking&nbsp;for<br />
the&nbsp;DBM.<br />
<br />
There&nbsp;are&nbsp;three&nbsp;kinds&nbsp;of&nbsp;way&nbsp;to&nbsp;receive&nbsp;method&nbsp;arguments.&nbsp;&nbsp;First,<br />
methods&nbsp;with&nbsp;a&nbsp;fixed&nbsp;number&nbsp;of&nbsp;arguments&nbsp;receive&nbsp;arguments&nbsp;like&nbsp;this:<br />
<br />
--<br />
static&nbsp;VALUE<br />
fdbm_delete(obj,&nbsp;keystr)<br />
&nbsp;&nbsp;&nbsp;&nbsp;VALUE&nbsp;obj,&nbsp;keystr;<br />
{<br />
&nbsp;&nbsp;:<br />
}<br />
--<br />
<br />
The&nbsp;first&nbsp;argument&nbsp;of&nbsp;the&nbsp;C&nbsp;function&nbsp;is&nbsp;the&nbsp;self,&nbsp;the&nbsp;rest&nbsp;are&nbsp;the<br />
arguments&nbsp;to&nbsp;the&nbsp;method.<br />
<br />
Second,&nbsp;methods&nbsp;with&nbsp;an&nbsp;arbitrary&nbsp;number&nbsp;of&nbsp;arguments&nbsp;receive<br />
arguments&nbsp;like&nbsp;this:<br />
<br />
--<br />
static&nbsp;VALUE<br />
fdbm_s_open(argc,&nbsp;argv,&nbsp;klass)<br />
&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;argc;<br />
&nbsp;&nbsp;&nbsp;&nbsp;VALUE&nbsp;*argv;<br />
&nbsp;&nbsp;&nbsp;&nbsp;VALUE&nbsp;klass;<br />
{<br />
&nbsp;&nbsp;:<br />
&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(rb_scan_args(argc,&nbsp;argv,&nbsp;&quot;11&quot;,&nbsp;&amp;file,&nbsp;&amp;vmode)&nbsp;==&nbsp;1)&nbsp;{<br />
&nbsp;&nbsp;mode&nbsp;=&nbsp;0666;&nbsp;&nbsp;/*&nbsp;default&nbsp;value&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;:<br />
}<br />
--<br />
<br />
The&nbsp;first&nbsp;argument&nbsp;is&nbsp;the&nbsp;number&nbsp;of&nbsp;method&nbsp;arguments,&nbsp;the&nbsp;second<br />
argument&nbsp;is&nbsp;the&nbsp;C&nbsp;array&nbsp;of&nbsp;the&nbsp;method&nbsp;arguments,&nbsp;and&nbsp;the&nbsp;third<br />
argument&nbsp;is&nbsp;the&nbsp;receiver&nbsp;of&nbsp;the&nbsp;method.<br />
<br />
You&nbsp;can&nbsp;use&nbsp;the&nbsp;function&nbsp;rb_scan_args()&nbsp;to&nbsp;check&nbsp;and&nbsp;retrieve&nbsp;the<br />
arguments.&nbsp;&nbsp;For&nbsp;example,&nbsp;&quot;11&quot;&nbsp;means&nbsp;that&nbsp;the&nbsp;method&nbsp;requires&nbsp;at&nbsp;least&nbsp;one<br />
argument,&nbsp;and&nbsp;at&nbsp;most&nbsp;receives&nbsp;two&nbsp;arguments.<br />
<br />
Methods&nbsp;with&nbsp;an&nbsp;arbitrary&nbsp;number&nbsp;of&nbsp;arguments&nbsp;can&nbsp;receive&nbsp;arguments<br />
by&nbsp;Ruby's&nbsp;array,&nbsp;like&nbsp;this:<br />
<br />
--<br />
static&nbsp;VALUE<br />
fdbm_indexes(obj,&nbsp;args)<br />
&nbsp;&nbsp;&nbsp;&nbsp;VALUE&nbsp;obj,&nbsp;args;<br />
{<br />
&nbsp;&nbsp;:<br />
}<br />
--<br />
<br />
The&nbsp;first&nbsp;argument&nbsp;is&nbsp;the&nbsp;receiver,&nbsp;the&nbsp;second&nbsp;one&nbsp;is&nbsp;the&nbsp;Ruby&nbsp;array<br />
which&nbsp;contains&nbsp;the&nbsp;arguments&nbsp;to&nbsp;the&nbsp;method.<br />
<br />
**&nbsp;Notice<br />
<br />
GC&nbsp;should&nbsp;know&nbsp;about&nbsp;global&nbsp;variables&nbsp;which&nbsp;refer&nbsp;to&nbsp;Ruby's&nbsp;objects,&nbsp;but<br />
are&nbsp;not&nbsp;exported&nbsp;to&nbsp;the&nbsp;Ruby&nbsp;world.&nbsp;&nbsp;You&nbsp;need&nbsp;to&nbsp;protect&nbsp;them&nbsp;by<br />
<br />
&nbsp;&nbsp;void&nbsp;rb_global_variable(VALUE&nbsp;*var)<br />
<br />
(5)&nbsp;prepare&nbsp;extconf.rb<br />
<br />
If&nbsp;the&nbsp;file&nbsp;named&nbsp;extconf.rb&nbsp;exists,&nbsp;it&nbsp;will&nbsp;be&nbsp;executed&nbsp;to&nbsp;generate<br />
Makefile.&nbsp;&nbsp;If&nbsp;not,&nbsp;the&nbsp;compilation&nbsp;scheme&nbsp;will&nbsp;try&nbsp;to&nbsp;generate&nbsp;Makefile<br />
anyway.<br />
<br />
extconf.rb&nbsp;is&nbsp;the&nbsp;file&nbsp;for&nbsp;check&nbsp;compilation&nbsp;conditions&nbsp;etc.&nbsp;&nbsp;You<br />
need&nbsp;to&nbsp;put<br />
<br />
&nbsp;&nbsp;require&nbsp;'mkmf'<br />
<br />
at&nbsp;the&nbsp;top&nbsp;of&nbsp;the&nbsp;file.&nbsp;&nbsp;You&nbsp;can&nbsp;use&nbsp;the&nbsp;functions&nbsp;below&nbsp;to&nbsp;check<br />
various&nbsp;conditions.<br />
<br />
&nbsp;&nbsp;have_library(lib,&nbsp;func):&nbsp;check&nbsp;whether&nbsp;library&nbsp;containing&nbsp;function&nbsp;exists.<br />
&nbsp;&nbsp;have_func(func,&nbsp;header):&nbsp;check&nbsp;whether&nbsp;function&nbsp;exists<br />
&nbsp;&nbsp;have_header(header):&nbsp;check&nbsp;whether&nbsp;header&nbsp;file&nbsp;exists<br />
&nbsp;&nbsp;create_makefile(target):&nbsp;generate&nbsp;Makefile<br />
<br />
The&nbsp;value&nbsp;of&nbsp;the&nbsp;variables&nbsp;below&nbsp;will&nbsp;affect&nbsp;the&nbsp;Makefile.<br />
<br />
&nbsp;&nbsp;$CFLAGS:&nbsp;included&nbsp;in&nbsp;CFLAGS&nbsp;make&nbsp;variable&nbsp;(such&nbsp;as&nbsp;-I)<br />
&nbsp;&nbsp;$LDFLAGS:&nbsp;included&nbsp;in&nbsp;LDFLAGS&nbsp;make&nbsp;variable&nbsp;(such&nbsp;as&nbsp;-L)<br />
<br />
If&nbsp;a&nbsp;compilation&nbsp;condition&nbsp;is&nbsp;not&nbsp;fulfilled,&nbsp;you&nbsp;should&nbsp;not&nbsp;call<br />
``create_makefile''.&nbsp;&nbsp;The&nbsp;Makefile&nbsp;will&nbsp;not&nbsp;generated,&nbsp;compilation&nbsp;will<br />
not&nbsp;be&nbsp;done.<br />
<br />
(6)&nbsp;prepare&nbsp;depend&nbsp;(optional)<br />
<br />
If&nbsp;the&nbsp;file&nbsp;named&nbsp;depend&nbsp;exists,&nbsp;Makefile&nbsp;will&nbsp;include&nbsp;that&nbsp;file&nbsp;to<br />
check&nbsp;dependencies.&nbsp;&nbsp;You&nbsp;can&nbsp;make&nbsp;this&nbsp;file&nbsp;by&nbsp;invoking<br />
<br />
&nbsp;&nbsp;%&nbsp;gcc&nbsp;-MM&nbsp;*.c&nbsp;&gt;&nbsp;depend<br />
<br />
It's&nbsp;no&nbsp;harm.&nbsp;&nbsp;Prepare&nbsp;it.<br />
<br />
(7)&nbsp;put&nbsp;file&nbsp;names&nbsp;into&nbsp;MANIFEST&nbsp;(optional)<br />
<br />
&nbsp;&nbsp;%&nbsp;find&nbsp;*&nbsp;-type&nbsp;f&nbsp;-print&nbsp;&gt;&nbsp;MANIFEST<br />
&nbsp;&nbsp;%&nbsp;vi&nbsp;MANIFEST<br />
<br />
Append&nbsp;file&nbsp;names&nbsp;into&nbsp;MANIFEST.&nbsp;&nbsp;The&nbsp;compilation&nbsp;scheme&nbsp;requires<br />
MANIFEST&nbsp;only&nbsp;to&nbsp;exist,&nbsp;but&nbsp;it's&nbsp;better&nbsp;to&nbsp;take&nbsp;this&nbsp;step&nbsp;in&nbsp;order<br />
to&nbsp;distinguish&nbsp;which&nbsp;files&nbsp;are&nbsp;required.<br />
<br />
(8)&nbsp;generate&nbsp;Makefile<br />
<br />
Try&nbsp;generating&nbsp;the&nbsp;Makefile&nbsp;by:<br />
<br />
&nbsp;&nbsp;ruby&nbsp;extconf.rb<br />
<br />
You&nbsp;don't&nbsp;need&nbsp;this&nbsp;step&nbsp;if&nbsp;you&nbsp;put&nbsp;the&nbsp;extension&nbsp;library&nbsp;under&nbsp;the&nbsp;ext<br />
directory&nbsp;of&nbsp;the&nbsp;ruby&nbsp;source&nbsp;tree.&nbsp;&nbsp;In&nbsp;that&nbsp;case,&nbsp;compilation&nbsp;of&nbsp;the<br />
interpreter&nbsp;will&nbsp;do&nbsp;this&nbsp;step&nbsp;for&nbsp;you.<br />
<br />
(9)&nbsp;make<br />
<br />
Type<br />
<br />
&nbsp;&nbsp;make<br />
<br />
to&nbsp;compile&nbsp;your&nbsp;extension.&nbsp;&nbsp;You&nbsp;don't&nbsp;need&nbsp;this&nbsp;step&nbsp;either&nbsp;if&nbsp;you&nbsp;have<br />
put&nbsp;extension&nbsp;library&nbsp;under&nbsp;the&nbsp;ext&nbsp;directory&nbsp;of&nbsp;the&nbsp;ruby&nbsp;source&nbsp;tree.<br />
<br />
(9)&nbsp;debug<br />
<br />
You&nbsp;may&nbsp;need&nbsp;to&nbsp;rb_debug&nbsp;the&nbsp;extension.&nbsp;&nbsp;Extensions&nbsp;can&nbsp;be&nbsp;linked<br />
statically&nbsp;by&nbsp;the&nbsp;adding&nbsp;directory&nbsp;name&nbsp;in&nbsp;the&nbsp;ext/Setup&nbsp;file&nbsp;so&nbsp;that<br />
you&nbsp;can&nbsp;inspect&nbsp;the&nbsp;extension&nbsp;with&nbsp;the&nbsp;debugger.<br />
<br />
(10)&nbsp;done,&nbsp;now&nbsp;you&nbsp;have&nbsp;the&nbsp;extension&nbsp;library<br />
<br />
You&nbsp;can&nbsp;do&nbsp;anything&nbsp;you&nbsp;want&nbsp;with&nbsp;your&nbsp;library.&nbsp;&nbsp;The&nbsp;author&nbsp;of&nbsp;Ruby<br />
will&nbsp;not&nbsp;claim&nbsp;any&nbsp;restrictions&nbsp;on&nbsp;your&nbsp;code&nbsp;depending&nbsp;on&nbsp;the&nbsp;Ruby&nbsp;API.<br />
Feel&nbsp;free&nbsp;to&nbsp;use,&nbsp;modify,&nbsp;distribute&nbsp;or&nbsp;sell&nbsp;your&nbsp;program.<br />
<br />
Appendix&nbsp;A.&nbsp;Ruby&nbsp;source&nbsp;files&nbsp;overview<br />
<br />
ruby&nbsp;language&nbsp;core<br />
<br />
&nbsp;&nbsp;class.c<br />
&nbsp;&nbsp;error.c<br />
&nbsp;&nbsp;eval.c<br />
&nbsp;&nbsp;gc.c<br />
&nbsp;&nbsp;object.c<br />
&nbsp;&nbsp;parse.y<br />
&nbsp;&nbsp;variable.c<br />
<br />
utility&nbsp;functions<br />
<br />
&nbsp;&nbsp;dln.c<br />
&nbsp;&nbsp;regex.c<br />
&nbsp;&nbsp;st.c<br />
&nbsp;&nbsp;util.c<br />
<br />
ruby&nbsp;interpreter&nbsp;implementation<br />
<br />
&nbsp;&nbsp;dmyext.c<br />
&nbsp;&nbsp;inits.c<br />
&nbsp;&nbsp;main.c<br />
&nbsp;&nbsp;ruby.c<br />
&nbsp;&nbsp;version.c<br />
<br />
class&nbsp;library<br />
<br />
&nbsp;&nbsp;array.c<br />
&nbsp;&nbsp;bignum.c<br />
&nbsp;&nbsp;compar.c<br />
&nbsp;&nbsp;dir.c<br />
&nbsp;&nbsp;enum.c<br />
&nbsp;&nbsp;file.c<br />
&nbsp;&nbsp;hash.c<br />
&nbsp;&nbsp;io.c<br />
&nbsp;&nbsp;marshal.c<br />
&nbsp;&nbsp;math.c<br />
&nbsp;&nbsp;numeric.c<br />
&nbsp;&nbsp;pack.c<br />
&nbsp;&nbsp;prec.c<br />
&nbsp;&nbsp;process.c<br />
&nbsp;&nbsp;random.c<br />
&nbsp;&nbsp;range.c<br />
&nbsp;&nbsp;re.c<br />
&nbsp;&nbsp;signal.c<br />
&nbsp;&nbsp;sprintf.c<br />
&nbsp;&nbsp;string.c<br />
&nbsp;&nbsp;struct.c<br />
&nbsp;&nbsp;time.c<br />
<br />
Appendix&nbsp;B.&nbsp;Ruby&nbsp;extension&nbsp;API&nbsp;reference<br />
<br />
**&nbsp;Types<br />
<br />
&nbsp;VALUE<br />
<br />
The&nbsp;type&nbsp;for&nbsp;the&nbsp;Ruby&nbsp;object.&nbsp;&nbsp;Actual&nbsp;structures&nbsp;are&nbsp;defined&nbsp;in&nbsp;ruby.h,<br />
such&nbsp;as&nbsp;struct&nbsp;RString,&nbsp;etc.&nbsp;&nbsp;To&nbsp;refer&nbsp;the&nbsp;values&nbsp;in&nbsp;structures,&nbsp;use<br />
casting&nbsp;macros&nbsp;like&nbsp;RSTRING(obj).<br />
<br />
**&nbsp;Variables&nbsp;and&nbsp;constants<br />
<br />
&nbsp;Qnil<br />
<br />
const:&nbsp;nil&nbsp;object<br />
<br />
&nbsp;Qtrue<br />
<br />
const:&nbsp;true&nbsp;object(default&nbsp;true&nbsp;value)<br />
<br />
&nbsp;Qfalse<br />
<br />
const:&nbsp;false&nbsp;object<br />
<br />
**&nbsp;C&nbsp;pointer&nbsp;wrapping<br />
<br />
&nbsp;Data_Wrap_Struct(VALUE&nbsp;klass,&nbsp;void&nbsp;(*mark)(),&nbsp;void&nbsp;(*free)(),&nbsp;void&nbsp;*sval)<br />
<br />
Wrap&nbsp;a&nbsp;C&nbsp;pointer&nbsp;into&nbsp;a&nbsp;Ruby&nbsp;object.&nbsp;&nbsp;If&nbsp;object&nbsp;has&nbsp;references&nbsp;to&nbsp;other<br />
Ruby&nbsp;objects,&nbsp;they&nbsp;should&nbsp;be&nbsp;marked&nbsp;by&nbsp;using&nbsp;the&nbsp;mark&nbsp;function&nbsp;during<br />
the&nbsp;GC&nbsp;process.&nbsp;&nbsp;Otherwise,&nbsp;mark&nbsp;should&nbsp;be&nbsp;0.&nbsp;&nbsp;When&nbsp;this&nbsp;object&nbsp;is&nbsp;no<br />
longer&nbsp;referred&nbsp;by&nbsp;anywhere,&nbsp;the&nbsp;pointer&nbsp;will&nbsp;be&nbsp;discarded&nbsp;by&nbsp;free<br />
function.<br />
<br />
&nbsp;Data_Make_Struct(klass,&nbsp;type,&nbsp;mark,&nbsp;free,&nbsp;sval)<br />
<br />
This&nbsp;macro&nbsp;allocates&nbsp;memory&nbsp;using&nbsp;malloc(),&nbsp;assigns&nbsp;it&nbsp;to&nbsp;the&nbsp;variable<br />
sval,&nbsp;and&nbsp;returns&nbsp;the&nbsp;DATA&nbsp;encapsulating&nbsp;the&nbsp;pointer&nbsp;to&nbsp;memory&nbsp;region.<br />
<br />
&nbsp;Data_Get_Struct(data,&nbsp;type,&nbsp;sval)<br />
<br />
This&nbsp;macro&nbsp;retrieves&nbsp;the&nbsp;pointer&nbsp;value&nbsp;from&nbsp;DATA,&nbsp;and&nbsp;assigns&nbsp;it&nbsp;to<br />
the&nbsp;variable&nbsp;sval.&nbsp;<br />
<br />
**&nbsp;Checking&nbsp;data&nbsp;types<br />
<br />
TYPE(value)<br />
FIXNUM_P(value)<br />
NIL_P(value)<br />
void&nbsp;Check_Type(VALUE&nbsp;value,&nbsp;int&nbsp;type)<br />
void&nbsp;Check_SafeStr(VALUE&nbsp;value)<br />
<br />
**&nbsp;Data&nbsp;type&nbsp;conversion<br />
<br />
FIX2INT(value)<br />
INT2FIX(i)<br />
NUM2INT(value)<br />
INT2NUM(i)<br />
NUM2DBL(value)<br />
rb_float_new(f)<br />
STR2CSTR(value)<br />
rb_str_new2(s)<br />
<br />
**&nbsp;defining&nbsp;class/module<br />
<br />
&nbsp;VALUE&nbsp;rb_define_class(const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;super)<br />
<br />
Defines&nbsp;a&nbsp;new&nbsp;Ruby&nbsp;class&nbsp;as&nbsp;a&nbsp;subclass&nbsp;of&nbsp;super.<br />
<br />
&nbsp;VALUE&nbsp;rb_define_class_under(VALUE&nbsp;module,&nbsp;const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;super)<br />
<br />
Creates&nbsp;a&nbsp;new&nbsp;Ruby&nbsp;class&nbsp;as&nbsp;a&nbsp;subclass&nbsp;of&nbsp;super,&nbsp;under&nbsp;the&nbsp;module's<br />
namespace.<br />
<br />
&nbsp;VALUE&nbsp;rb_define_module(const&nbsp;char&nbsp;*name)<br />
<br />
Defines&nbsp;a&nbsp;new&nbsp;Ruby&nbsp;module.<br />
<br />
&nbsp;VALUE&nbsp;rb_define_module_under(VALUE&nbsp;module,&nbsp;const&nbsp;char&nbsp;*name)<br />
<br />
Defines&nbsp;a&nbsp;new&nbsp;Ruby&nbsp;module&nbsp;under&nbsp;the&nbsp;module's&nbsp;namespace.<br />
<br />
&nbsp;void&nbsp;rb_include_module(VALUE&nbsp;klass,&nbsp;VALUE&nbsp;module)<br />
<br />
Includes&nbsp;module&nbsp;into&nbsp;class.&nbsp;&nbsp;If&nbsp;class&nbsp;already&nbsp;includes&nbsp;it,&nbsp;just<br />
ignored.<br />
<br />
&nbsp;void&nbsp;rb_extend_object(VALUE&nbsp;object,&nbsp;VALUE&nbsp;module)<br />
<br />
Extend&nbsp;the&nbsp;object&nbsp;with&nbsp;the&nbsp;module's&nbsp;attributes.<br />
<br />
**&nbsp;Defining&nbsp;Global&nbsp;Variables<br />
<br />
&nbsp;void&nbsp;rb_define_variable(const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;*var)<br />
<br />
Defines&nbsp;a&nbsp;global&nbsp;variable&nbsp;which&nbsp;is&nbsp;shared&nbsp;between&nbsp;C&nbsp;and&nbsp;Ruby.&nbsp;&nbsp;If&nbsp;name<br />
contains&nbsp;a&nbsp;character&nbsp;which&nbsp;is&nbsp;not&nbsp;allowed&nbsp;to&nbsp;be&nbsp;part&nbsp;of&nbsp;the&nbsp;symbol,<br />
it&nbsp;can't&nbsp;be&nbsp;seen&nbsp;from&nbsp;Ruby&nbsp;programs.<br />
<br />
&nbsp;void&nbsp;rb_define_readonly_variable(const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;*var)<br />
<br />
Defines&nbsp;a&nbsp;read-only&nbsp;global&nbsp;variable.&nbsp;&nbsp;Works&nbsp;just&nbsp;like<br />
rb_define_variable(),&nbsp;except&nbsp;defined&nbsp;variable&nbsp;is&nbsp;read-only.<br />
<br />
&nbsp;void&nbsp;rb_define_virtual_variable(const&nbsp;char&nbsp;*name,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VALUE&nbsp;(*getter)(),&nbsp;VALUE&nbsp;(*setter)())<br />
<br />
Defines&nbsp;a&nbsp;virtual&nbsp;variable,&nbsp;whose&nbsp;behavior&nbsp;is&nbsp;defined&nbsp;by&nbsp;a&nbsp;pair&nbsp;of&nbsp;C<br />
functions.&nbsp;&nbsp;The&nbsp;getter&nbsp;function&nbsp;is&nbsp;called&nbsp;when&nbsp;the&nbsp;variable&nbsp;is<br />
referred.&nbsp;&nbsp;The&nbsp;setter&nbsp;function&nbsp;is&nbsp;called&nbsp;when&nbsp;the&nbsp;value&nbsp;is&nbsp;set&nbsp;to&nbsp;the<br />
variable.&nbsp;&nbsp;The&nbsp;prototype&nbsp;for&nbsp;getter/setter&nbsp;functions&nbsp;are:<br />
<br />
&nbsp;&nbsp;VALUE&nbsp;getter(ID&nbsp;id)<br />
&nbsp;&nbsp;void&nbsp;setter(VALUE&nbsp;val,&nbsp;ID&nbsp;id)<br />
<br />
The&nbsp;getter&nbsp;function&nbsp;must&nbsp;return&nbsp;the&nbsp;value&nbsp;for&nbsp;the&nbsp;access.<br />
<br />
&nbsp;void&nbsp;rb_define_hooked_variable(const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;*var,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VALUE&nbsp;(*getter)(),&nbsp;VALUE&nbsp;(*setter)())<br />
<br />
Defines&nbsp;hooked&nbsp;variable.&nbsp;&nbsp;It's&nbsp;a&nbsp;virtual&nbsp;variable&nbsp;with&nbsp;a&nbsp;C&nbsp;variable.&nbsp;&nbsp;<br />
The&nbsp;getter&nbsp;is&nbsp;called&nbsp;as<br />
<br />
&nbsp;&nbsp;VALUE&nbsp;getter(ID&nbsp;id,&nbsp;VALUE&nbsp;*var)<br />
<br />
returning&nbsp;a&nbsp;new&nbsp;value.&nbsp;&nbsp;The&nbsp;setter&nbsp;is&nbsp;called&nbsp;as<br />
<br />
&nbsp;&nbsp;void&nbsp;setter(VALUE&nbsp;val,&nbsp;ID&nbsp;id,&nbsp;VALUE&nbsp;*var)<br />
<br />
GC&nbsp;requires&nbsp;C&nbsp;global&nbsp;variables&nbsp;which&nbsp;hold&nbsp;Ruby&nbsp;values&nbsp;to&nbsp;be&nbsp;marked.<br />
<br />
&nbsp;void&nbsp;rb_global_variable(VALUE&nbsp;*var)<br />
<br />
Tells&nbsp;GC&nbsp;to&nbsp;protect&nbsp;these&nbsp;variables.<br />
<br />
**&nbsp;Constant&nbsp;Definition<br />
<br />
&nbsp;void&nbsp;rb_define_const(VALUE&nbsp;klass,&nbsp;const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;val)<br />
<br />
Defines&nbsp;a&nbsp;new&nbsp;constant&nbsp;under&nbsp;the&nbsp;class/module.<br />
<br />
&nbsp;void&nbsp;rb_define_global_const(const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;val)<br />
<br />
Defines&nbsp;a&nbsp;global&nbsp;constant.&nbsp;&nbsp;This&nbsp;is&nbsp;just&nbsp;the&nbsp;same&nbsp;as<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rb_define_const(cKernal,&nbsp;name,&nbsp;val)<br />
<br />
**&nbsp;Method&nbsp;Definition<br />
<br />
&nbsp;rb_define_method(VALUE&nbsp;klass,&nbsp;const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;(*func)(),&nbsp;int&nbsp;argc)<br />
<br />
Defines&nbsp;a&nbsp;method&nbsp;for&nbsp;the&nbsp;class.&nbsp;&nbsp;func&nbsp;is&nbsp;the&nbsp;function&nbsp;pointer.&nbsp;&nbsp;argc<br />
is&nbsp;the&nbsp;number&nbsp;of&nbsp;arguments.&nbsp;&nbsp;if&nbsp;argc&nbsp;is&nbsp;-1,&nbsp;the&nbsp;function&nbsp;will&nbsp;receive<br />
3&nbsp;arguments:&nbsp;argc,&nbsp;argv,&nbsp;and&nbsp;self.&nbsp;&nbsp;if&nbsp;argc&nbsp;is&nbsp;-2,&nbsp;the&nbsp;function&nbsp;will<br />
receive&nbsp;2&nbsp;arguments,&nbsp;self&nbsp;and&nbsp;args,&nbsp;where&nbsp;args&nbsp;is&nbsp;a&nbsp;Ruby&nbsp;array&nbsp;of<br />
the&nbsp;method&nbsp;arguments.<br />
<br />
&nbsp;rb_define_private_method(VALUE&nbsp;klass,&nbsp;const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;(*func)(),&nbsp;int&nbsp;argc)<br />
<br />
Defines&nbsp;a&nbsp;private&nbsp;method&nbsp;for&nbsp;the&nbsp;class.&nbsp;&nbsp;Arguments&nbsp;are&nbsp;same&nbsp;as<br />
rb_define_method().<br />
<br />
&nbsp;rb_define_singleton_method(VALUE&nbsp;klass,&nbsp;const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;(*func)(),&nbsp;int&nbsp;argc)<br />
<br />
Defines&nbsp;a&nbsp;singleton&nbsp;method.&nbsp;&nbsp;Arguments&nbsp;are&nbsp;same&nbsp;as&nbsp;rb_define_method().<br />
<br />
&nbsp;rb_scan_args(int&nbsp;argc,&nbsp;VALUE&nbsp;*argv,&nbsp;const&nbsp;char&nbsp;*fmt,&nbsp;...)<br />
<br />
Retrieve&nbsp;argument&nbsp;from&nbsp;argc,&nbsp;argv.&nbsp;&nbsp;The&nbsp;fmt&nbsp;is&nbsp;the&nbsp;format&nbsp;string&nbsp;for<br />
the&nbsp;arguments,&nbsp;such&nbsp;as&nbsp;&quot;12&quot;&nbsp;for&nbsp;1&nbsp;non-optional&nbsp;argument,&nbsp;2&nbsp;optional<br />
arguments.&nbsp;&nbsp;If&nbsp;`*'&nbsp;appears&nbsp;at&nbsp;the&nbsp;end&nbsp;of&nbsp;fmt,&nbsp;it&nbsp;means&nbsp;the&nbsp;rest&nbsp;of<br />
the&nbsp;arguments&nbsp;are&nbsp;assigned&nbsp;to&nbsp;the&nbsp;corresponding&nbsp;variable,&nbsp;packed&nbsp;in<br />
an&nbsp;array.<br />
<br />
**&nbsp;Invoking&nbsp;Ruby&nbsp;method<br />
<br />
&nbsp;VALUE&nbsp;rb_funcall(VALUE&nbsp;recv,&nbsp;ID&nbsp;mid,&nbsp;int&nbsp;narg,&nbsp;...)<br />
<br />
Invokes&nbsp;a&nbsp;method.&nbsp;&nbsp;To&nbsp;retrieve&nbsp;mid&nbsp;from&nbsp;a&nbsp;method&nbsp;name,&nbsp;use&nbsp;rb_intern().<br />
<br />
&nbsp;VALUE&nbsp;rb_funcall2(VALUE&nbsp;recv,&nbsp;ID&nbsp;mid,&nbsp;int&nbsp;argc,&nbsp;VALUE&nbsp;*argv)<br />
<br />
Invokes&nbsp;a&nbsp;method,&nbsp;passing&nbsp;arguments&nbsp;by&nbsp;an&nbsp;array&nbsp;of&nbsp;values.<br />
<br />
&nbsp;VALUE&nbsp;rb_eval_string(const&nbsp;char&nbsp;*str)<br />
<br />
Compiles&nbsp;and&nbsp;executes&nbsp;the&nbsp;string&nbsp;as&nbsp;a&nbsp;Ruby&nbsp;program.<br />
<br />
&nbsp;ID&nbsp;rb_intern(const&nbsp;char&nbsp;*name)<br />
<br />
Returns&nbsp;ID&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;name.<br />
<br />
&nbsp;char&nbsp;*rb_id2name(ID&nbsp;id)<br />
<br />
Returns&nbsp;the&nbsp;name&nbsp;corresponding&nbsp;ID.<br />
<br />
&nbsp;char&nbsp;*rb_class2name(VALUE&nbsp;klass)<br />
<br />
Returns&nbsp;the&nbsp;name&nbsp;of&nbsp;the&nbsp;class.<br />
<br />
&nbsp;int&nbsp;rb_respond_to(VALUE&nbsp;object,&nbsp;ID&nbsp;id)<br />
<br />
Returns&nbsp;true&nbsp;if&nbsp;the&nbsp;object&nbsp;responds&nbsp;to&nbsp;the&nbsp;message&nbsp;specified&nbsp;by&nbsp;id.<br />
<br />
**&nbsp;Instance&nbsp;Variables<br />
<br />
&nbsp;VALUE&nbsp;rb_iv_get(VALUE&nbsp;obj,&nbsp;const&nbsp;char&nbsp;*name)<br />
<br />
Retrieve&nbsp;the&nbsp;value&nbsp;of&nbsp;the&nbsp;instance&nbsp;variable.&nbsp;&nbsp;If&nbsp;the&nbsp;name&nbsp;is&nbsp;not<br />
prefixed&nbsp;by&nbsp;`@',&nbsp;that&nbsp;variable&nbsp;shall&nbsp;be&nbsp;inaccessible&nbsp;from&nbsp;Ruby.<br />
<br />
&nbsp;VALUE&nbsp;rb_iv_set(VALUE&nbsp;obj,&nbsp;const&nbsp;char&nbsp;*name,&nbsp;VALUE&nbsp;val)<br />
<br />
Sets&nbsp;the&nbsp;value&nbsp;of&nbsp;the&nbsp;instance&nbsp;variable.<br />
<br />
**&nbsp;Control&nbsp;Structure<br />
<br />
&nbsp;VALUE&nbsp;rb_iterate(VALUE&nbsp;(*func1)(),&nbsp;void&nbsp;*arg1,&nbsp;VALUE&nbsp;(*func2)(),&nbsp;void&nbsp;*arg2)<br />
<br />
Calls&nbsp;the&nbsp;function&nbsp;func1,&nbsp;supplying&nbsp;func2&nbsp;as&nbsp;the&nbsp;block.&nbsp;&nbsp;func1&nbsp;will&nbsp;be<br />
called&nbsp;with&nbsp;the&nbsp;argument&nbsp;arg1.&nbsp;&nbsp;func2&nbsp;receives&nbsp;the&nbsp;value&nbsp;from&nbsp;yield&nbsp;as<br />
the&nbsp;first&nbsp;argument,&nbsp;arg2&nbsp;as&nbsp;the&nbsp;second&nbsp;argument.<br />
&nbsp;<br />
&nbsp;VALUE&nbsp;rb_yield(VALUE&nbsp;val)<br />
<br />
Evaluates&nbsp;the&nbsp;block&nbsp;with&nbsp;value&nbsp;val.<br />
<br />
&nbsp;VALUE&nbsp;rb_rescue(VALUE&nbsp;(*func1)(),&nbsp;void&nbsp;*arg1,&nbsp;VALUE&nbsp;(*func2)(),&nbsp;void&nbsp;*arg2)<br />
<br />
Calls&nbsp;the&nbsp;function&nbsp;func1,&nbsp;with&nbsp;arg1&nbsp;as&nbsp;the&nbsp;argument.&nbsp;&nbsp;If&nbsp;an&nbsp;exception<br />
occurs&nbsp;during&nbsp;func1,&nbsp;it&nbsp;calls&nbsp;func2&nbsp;with&nbsp;arg2&nbsp;as&nbsp;the&nbsp;argument.&nbsp;&nbsp;The<br />
return&nbsp;value&nbsp;of&nbsp;rb_rescue()&nbsp;is&nbsp;the&nbsp;return&nbsp;value&nbsp;from&nbsp;func1&nbsp;if&nbsp;no<br />
exception&nbsp;occurs,&nbsp;from&nbsp;func2&nbsp;otherwise.<br />
<br />
&nbsp;VALUE&nbsp;rb_ensure(VALUE&nbsp;(*func1)(),&nbsp;void&nbsp;*arg1,&nbsp;void&nbsp;(*func2)(),&nbsp;void&nbsp;*arg2)<br />
<br />
Calls&nbsp;the&nbsp;function&nbsp;func1&nbsp;with&nbsp;arg1&nbsp;as&nbsp;the&nbsp;argument,&nbsp;then&nbsp;calls&nbsp;func2<br />
with&nbsp;arg2&nbsp;if&nbsp;execution&nbsp;terminated.&nbsp;&nbsp;The&nbsp;return&nbsp;value&nbsp;from<br />
rb_ensure()&nbsp;is&nbsp;that&nbsp;of&nbsp;func1.<br />
<br />
**&nbsp;Exceptions&nbsp;and&nbsp;Errors<br />
<br />
&nbsp;void&nbsp;rb_warn(const&nbsp;char&nbsp;*fmt,&nbsp;...)<br />
<br />
Prints&nbsp;a&nbsp;warning&nbsp;message&nbsp;according&nbsp;to&nbsp;a&nbsp;printf-like&nbsp;format.<br />
<br />
&nbsp;void&nbsp;rb_warning(const&nbsp;char&nbsp;*fmt,&nbsp;...)<br />
<br />
Prints&nbsp;a&nbsp;warning&nbsp;message&nbsp;according&nbsp;to&nbsp;a&nbsp;printf-like&nbsp;format,&nbsp;if<br />
$VERBOSE&nbsp;is&nbsp;true.<br />
<br />
void&nbsp;rb_raise(rb_eRuntimeError,&nbsp;const&nbsp;char&nbsp;*fmt,&nbsp;...)<br />
<br />
Raises&nbsp;RuntimeError.&nbsp;&nbsp;The&nbsp;fmt&nbsp;is&nbsp;a&nbsp;format&nbsp;string&nbsp;just&nbsp;like&nbsp;printf().<br />
<br />
&nbsp;void&nbsp;rb_raise(VALUE&nbsp;exception,&nbsp;const&nbsp;char&nbsp;*fmt,&nbsp;...)<br />
<br />
Raises&nbsp;a&nbsp;class&nbsp;exception.&nbsp;&nbsp;The&nbsp;fmt&nbsp;is&nbsp;a&nbsp;format&nbsp;string&nbsp;just&nbsp;like&nbsp;printf().<br />
<br />
&nbsp;void&nbsp;rb_fatal(const&nbsp;char&nbsp;*fmt,&nbsp;...)<br />
<br />
Raises&nbsp;a&nbsp;fatal&nbsp;error,&nbsp;terminates&nbsp;the&nbsp;interpreter.&nbsp;&nbsp;No&nbsp;exception&nbsp;handling<br />
will&nbsp;be&nbsp;done&nbsp;for&nbsp;fatal&nbsp;errors,&nbsp;but&nbsp;ensure&nbsp;blocks&nbsp;will&nbsp;be&nbsp;executed.<br />
<br />
&nbsp;void&nbsp;rb_bug(const&nbsp;char&nbsp;*fmt,&nbsp;...)<br />
<br />
Terminates&nbsp;the&nbsp;interpreter&nbsp;immediately.&nbsp;&nbsp;This&nbsp;function&nbsp;should&nbsp;be<br />
called&nbsp;under&nbsp;the&nbsp;situation&nbsp;caused&nbsp;by&nbsp;the&nbsp;bug&nbsp;in&nbsp;the&nbsp;interpreter.&nbsp;&nbsp;No<br />
exception&nbsp;handling&nbsp;nor&nbsp;ensure&nbsp;execution&nbsp;will&nbsp;be&nbsp;done.<br />
<br />
**&nbsp;Initialize&nbsp;and&nbsp;Starts&nbsp;the&nbsp;Interpreter<br />
<br />
The&nbsp;embedding&nbsp;API&nbsp;functions&nbsp;are&nbsp;below&nbsp;(not&nbsp;needed&nbsp;for&nbsp;extension&nbsp;libraries):<br />
<br />
&nbsp;void&nbsp;ruby_init()<br />
<br />
Initializes&nbsp;the&nbsp;interpreter.<br />
<br />
&nbsp;void&nbsp;ruby_options(int&nbsp;argc,&nbsp;char&nbsp;**argv)<br />
<br />
Process&nbsp;command&nbsp;line&nbsp;arguments&nbsp;for&nbsp;the&nbsp;interpreter.<br />
<br />
&nbsp;void&nbsp;ruby_run()<br />
<br />
Starts&nbsp;execution&nbsp;of&nbsp;the&nbsp;interpreter.<br />
<br />
&nbsp;void&nbsp;ruby_script(char&nbsp;*name)<br />
<br />
Specifies&nbsp;the&nbsp;name&nbsp;of&nbsp;the&nbsp;script&nbsp;($0).<br />
<br />
Appendix&nbsp;C.&nbsp;Functions&nbsp;Available&nbsp;in&nbsp;extconf.rb<br />
<br />
These&nbsp;functions&nbsp;are&nbsp;available&nbsp;in&nbsp;extconf.rb:<br />
<br />
&nbsp;have_library(lib,&nbsp;func)<br />
<br />
Checks&nbsp;whether&nbsp;the&nbsp;library&nbsp;exists,&nbsp;containing&nbsp;the&nbsp;specified&nbsp;function.<br />
Returns&nbsp;true&nbsp;if&nbsp;the&nbsp;library&nbsp;exists.<br />
<br />
&nbsp;find_library(lib,&nbsp;func,&nbsp;path...)<br />
<br />
Checks&nbsp;whether&nbsp;a&nbsp;library&nbsp;which&nbsp;contains&nbsp;the&nbsp;specified&nbsp;function&nbsp;exists&nbsp;in<br />
path.&nbsp;&nbsp;Returns&nbsp;true&nbsp;if&nbsp;the&nbsp;library&nbsp;exists.<br />
<br />
&nbsp;have_func(func,&nbsp;header)<br />
<br />
Checks&nbsp;whether&nbsp;func&nbsp;exists&nbsp;with&nbsp;header.&nbsp;&nbsp;Returns&nbsp;true&nbsp;if&nbsp;the&nbsp;function<br />
exists.&nbsp;&nbsp;To&nbsp;check&nbsp;functions&nbsp;in&nbsp;an&nbsp;additional&nbsp;library,&nbsp;you&nbsp;need&nbsp;to<br />
check&nbsp;that&nbsp;library&nbsp;first&nbsp;using&nbsp;have_library().<br />
<br />
&nbsp;have_header(header)<br />
<br />
Checks&nbsp;whether&nbsp;header&nbsp;exists.&nbsp;&nbsp;Returns&nbsp;true&nbsp;if&nbsp;the&nbsp;header&nbsp;file&nbsp;exists.<br />
<br />
&nbsp;create_makefile(target)<br />
<br />
Generates&nbsp;the&nbsp;Makefile&nbsp;for&nbsp;the&nbsp;extension&nbsp;library.&nbsp;&nbsp;If&nbsp;you&nbsp;don't&nbsp;invoke<br />
this&nbsp;method,&nbsp;the&nbsp;compilation&nbsp;will&nbsp;not&nbsp;be&nbsp;done.<br />
<br />
&nbsp;with_config(withval[,&nbsp;default=nil])<br />
<br />
Parses&nbsp;the&nbsp;command&nbsp;line&nbsp;options&nbsp;and&nbsp;returns&nbsp;the&nbsp;value&nbsp;specified&nbsp;by<br />
--with-&lt;withval&gt;.<br />
<br />
&nbsp;dir_config(target[,&nbsp;default_dir])<br />
&nbsp;dir_config(target[,&nbsp;default_include,&nbsp;default_lib])<br />
<br />
Parses&nbsp;the&nbsp;command&nbsp;line&nbsp;options&nbsp;and&nbsp;adds&nbsp;the&nbsp;directories&nbsp;specified&nbsp;by<br />
--with-&lt;target&gt;-dir,&nbsp;--with-&lt;target&gt;-include,&nbsp;and/or&nbsp;--with-&lt;target&gt;-lib<br />
to&nbsp;$CFLAGS&nbsp;and/or&nbsp;$LDFLAGS.&nbsp;&nbsp;--with-&lt;target&gt;-dir=/path&nbsp;is&nbsp;equivalent&nbsp;to<br />
--with-&lt;target&gt;-include=/path/include&nbsp;--with-&lt;target&gt;-lib=/path/lib.<br />
Returns&nbsp;an&nbsp;array&nbsp;of&nbsp;the&nbsp;added&nbsp;directories&nbsp;([include_dir,&nbsp;lib_dir]).<br />
<br />
/*<br />
&nbsp;*&nbsp;Local&nbsp;variables:<br />
&nbsp;*&nbsp;fill-column:&nbsp;70<br />
&nbsp;*&nbsp;end:<br />
&nbsp;*/<br />


<hr />
<div class="navigator"><span class="navigator">[<a href="index.html">MAIN</a>][<a href="refm482.html">INDEX</a>][<a href="refm483.html">KEYWORD</a>][<a href="refm594.html">METHOD</a>(<a href="refm633.html">NC</a>)]&nbsp;&nbsp;&nbsp;[<a href="index.html">TOP</a>][<a href="index.html">UP</a>][<a href="refm473.html">&lt;-PREV</a>][<a href="refm475.html">NEXT-&gt;</a>]</span></div>

</body>
</html>