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