Nobuyoshi Nakada
9/7/2006 3:54:00 AM
Hi,
At Thu, 7 Sep 2006 05:04:12 +0900,
Joel VanderWerf wrote in [ruby-talk:213012]:
> >>>> extern VALUE rb_cSocket;
> >>>>
> >>>> in your extension. I've done that before.
> >>> It doesn't work always on all platforms.
> >> Will it eventually be externed in ruby.h then?
> >
> > It isn't the point. Dynamically loaded symbols may not visible
> > from other loaded libraries.
> >
>
> Socket is a pretty popular library. Maybe rb_cSocket could be declared
> in IO.c?
It would be popular indeed, but is an extension library, which may or
may not be loaded. By just accessing, it can be zero if it hasn't
been loaded yet. So you need to ensure it got loaded:
rb_require("socket");
rb_funcall(rb_cTCPSocket, rb_intern("for_fd"), 1, INT2NUM(socket));
I guess this might be better with autoloading.
rb_funcall(rb_path2class("TCPSocket"), rb_intern("for_fd"), 1,
INT2NUM(socket));
This is a script to generate autoloading code.
#!./miniruby -s
Top = "rb_cObject"
class String
if File::ALT_SEPARATOR
def proppath
tr!(File::ALT_SEPARATOR, File::SEPARATOR)
self
end
else
def proppath
self
end
end
end
$srcdir.proppath if $srcdir
header = "ruby.h"
header = File.join($srcdir, header) if $srcdir
stdmod = {}
IO.foreach(header) do |line|
if n = line[/^RUBY_EXTERN\s+VALUE\s+(rb_[mc]\w+);/, 1]
stdmod[n] = true
end
end
if ARGV.empty?
ext = "ext"
ext = File.join($srcdir, ext) if $srcdir
dirs = [ext]
else
dirs = ARGV.collect {|d| d.proppath}
end
if $srcdir
srcpre = %r"\A#{Regexp.quote($srcdir)}/"
else
srcpre = /\A/
end
dirs.collect! do |d|
if File.basename(d) == "extconf.rb"
d
else
Dir.glob(File.join(d, "**/extconf.rb"))
end
end
dirs.flatten!
region = " /* begin autoload */"
dirs.each do |e|
if File.directory?(e) and !File.exist?(e = File.join(e, "extconf.rb"))
next
end
comment = "\n /* #{File.dirname(e.sub(srcpre, ''))} */"
modname = IO.read(e)[/create_makefile\s*[\s\(]([\'\"])(.*?)\1\s*\)?/,
2] or next
ARGV.replace(Dir.glob(File.join(File.dirname(e), "*.c")))
ARGF.each do |line|
/\brb_define_(?:class|module)(?:\s*\(|_under\s*\((\w+)\s*,)?\s*("\w+")/
=~ line or next
name, mod = $2, $1
if !mod
mod = Top
elsif !stdmod[mod]
next
end
if comment
if region
puts region
region = nil
end
puts comment
comment = nil
end
puts " rb_autoload(#{mod}, rb_intern(#{name}), \"#{modname}\");"
end
end
puts "\n /* end autoload */" unless region
--
Nobu Nakada