Static functions, extensions, linkage

Discussion in 'Ruby' started by Daniel Berger, Aug 2, 2006.

  1. Hi,

    How do you get at a static function from within a C extension? I tried
    this snippet where I attempt to use flo_plus from numeric.c:

    /* foo.c */
    #include <ruby.h>

    extern VALUE flo_plus(VALUE, VALUE);

    static VALUE foo_test(VALUE x, VALUE y){
    return flo_plus(x, y);
    }

    void Init_foo(){
    VALUE cFoo = rb_define_class("Foo", rb_cObject);
    rb_define_method(cFoo, "test", foo_test, 2);
    }

    # test.rb
    $:unshift Dir.pwd
    require 'foo'
    f = Foo.new
    f.test

    This result is:

    ruby: symbol lookup error:
    /home/djberge/programming/ruby/extensions/foo.so: undefined symbol:
    flo_plus

    I tried linking explicitly against -lruby but that didn't help.

    Regards,

    Dan
    Daniel Berger, Aug 2, 2006
    #1
    1. Advertising

  2. Daniel Berger wrote:
    > Hi,
    >
    > How do you get at a static function from within a C extension? I tried
    > this snippet where I attempt to use flo_plus from numeric.c:
    >
    > /* foo.c */
    > #include <ruby.h>
    >
    > extern VALUE flo_plus(VALUE, VALUE);
    >
    > static VALUE foo_test(VALUE x, VALUE y){
    > return flo_plus(x, y);
    > }
    >
    > void Init_foo(){
    > VALUE cFoo = rb_define_class("Foo", rb_cObject);
    > rb_define_method(cFoo, "test", foo_test, 2);
    > }
    >
    > # test.rb
    > $:unshift Dir.pwd
    > require 'foo'
    > f = Foo.new
    > f.test
    >
    > This result is:
    >
    > ruby: symbol lookup error:
    > /home/djberge/programming/ruby/extensions/foo.so: undefined symbol:
    > flo_plus
    >
    > I tried linking explicitly against -lruby but that didn't help.
    >
    > Regards,
    >
    > Dan
    >
    >
    >

    Where is 'flo_plus' defined?
    Timothy Hunter, Aug 2, 2006
    #2
    1. Advertising

  3. Timothy Hunter wrote:
    > Daniel Berger wrote:
    > > Hi,
    > >
    > > How do you get at a static function from within a C extension? I tried
    > > this snippet where I attempt to use flo_plus from numeric.c:
    > >
    > > /* foo.c */
    > > #include <ruby.h>
    > >
    > > extern VALUE flo_plus(VALUE, VALUE);
    > >
    > > static VALUE foo_test(VALUE x, VALUE y){
    > > return flo_plus(x, y);
    > > }
    > >
    > > void Init_foo(){
    > > VALUE cFoo = rb_define_class("Foo", rb_cObject);
    > > rb_define_method(cFoo, "test", foo_test, 2);
    > > }
    > >
    > > # test.rb
    > > $:unshift Dir.pwd
    > > require 'foo'
    > > f = Foo.new
    > > f.test
    > >
    > > This result is:
    > >
    > > ruby: symbol lookup error:
    > > /home/djberge/programming/ruby/extensions/foo.so: undefined symbol:
    > > flo_plus
    > >
    > > I tried linking explicitly against -lruby but that didn't help.
    > >
    > > Regards,
    > >
    > > Dan
    > >
    > >
    > >

    > Where is 'flo_plus' defined?


    In numeric.c. Note that it *builds* fine, it just doesn't *run*.

    Regards,

    Dan
    Daniel Berger, Aug 2, 2006
    #3
  4. Daniel Berger wrote:
    > Timothy Hunter wrote:
    >
    >> Daniel Berger wrote:
    >>
    >>> Hi,
    >>>
    >>> How do you get at a static function from within a C extension? I tried
    >>> this snippet where I attempt to use flo_plus from numeric.c:
    >>>
    >>> /* foo.c */
    >>> #include <ruby.h>
    >>>
    >>> extern VALUE flo_plus(VALUE, VALUE);
    >>>
    >>> static VALUE foo_test(VALUE x, VALUE y){
    >>> return flo_plus(x, y);
    >>> }
    >>>
    >>> void Init_foo(){
    >>> VALUE cFoo = rb_define_class("Foo", rb_cObject);
    >>> rb_define_method(cFoo, "test", foo_test, 2);
    >>> }
    >>>
    >>> # test.rb
    >>> $:unshift Dir.pwd
    >>> require 'foo'
    >>> f = Foo.new
    >>> f.test
    >>>
    >>> This result is:
    >>>
    >>> ruby: symbol lookup error:
    >>> /home/djberge/programming/ruby/extensions/foo.so: undefined symbol:
    >>> flo_plus
    >>>
    >>> I tried linking explicitly against -lruby but that didn't help.
    >>>
    >>> Regards,
    >>>
    >>> Dan
    >>>
    >>>
    >>>
    >>>

    >> Where is 'flo_plus' defined?
    >>

    >
    > In numeric.c. Note that it *builds* fine, it just doesn't *run*.
    >
    > Regards,
    >
    > Dan
    >
    >
    >

    I see. Since flo_plus has static linkage in numeric.c you can't call it
    from your extension. It builds okay because you supplied a declaration
    for it, and it links okay because Linux does lazy linking (that is,
    external symbols aren't resolved until the .so gets loaded), but it
    won't run because there's no external definition of flo_plus to match
    your external reference.

    You'll have to use rb_funcall to call "+".
    Timothy Hunter, Aug 2, 2006
    #4
  5. On Aug 1, 2006, at 8:10 PM, Daniel Berger wrote:

    > Hi,
    >
    > How do you get at a static function from within a C extension? I
    > tried
    > this snippet where I attempt to use flo_plus from numeric.c:


    I could be wrong, but I believe the entire purpose of a static
    function is to _not_ be get at able from other code (sort of like
    private in ruby).
    Logan Capaldo, Aug 2, 2006
    #5
  6. Hello !

    >
    > This result is:
    >
    > ruby: symbol lookup error:
    > /home/djberge/programming/ruby/extensions/foo.so: undefined symbol:
    > flo_plus
    >
    > I tried linking explicitly against -lruby but that didn't help.


    By the way, if you're interested to know which symbols are exported
    from a library, just do

    nm -D /usr/lib/library.so

    A look to that on my computer shows no references to flo_plus, only:
    nm -D /usr/lib/libruby1.8.so | grep flo
    U flock
    U floor
    0000000000057ef0 T rb_float_new

    Cheers

    Vincent
    Vincent Fourmond, Aug 2, 2006
    #6
  7. Daniel Berger

    Tim Hunter Guest

    Vincent Fourmond wrote:
    >
    > By the way, if you're interested to know which symbols are exported
    > from a library, just do
    >
    > nm -D /usr/lib/library.so
    >
    > A look to that on my computer shows no references to flo_plus, only:
    > nm -D /usr/lib/libruby1.8.so | grep flo
    > U flock
    > U floor
    > 0000000000057ef0 T rb_float_new



    In Ruby, the functions that are intended for use by extensions start
    with the prefix "rb_" and are declared in either ruby.h or intern.h.
    Since flo_plus doesn't start with "rb_" it isn't intended to be
    available to extensions.
    Tim Hunter, Aug 2, 2006
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. pembed2003

    scope, static and linkage

    pembed2003, May 26, 2004, in forum: C++
    Replies:
    6
    Views:
    522
    pembed2003
    May 27, 2004
  2. Bill Pursell

    simulating private member functions--static linkage

    Bill Pursell, Apr 27, 2006, in forum: C Programming
    Replies:
    4
    Views:
    321
    Michael Wojcik
    May 1, 2006
  3. tropos
    Replies:
    3
    Views:
    445
  4. Nagrik
    Replies:
    5
    Views:
    466
    James Kanze
    Nov 28, 2007
  5. Replies:
    1
    Views:
    574
    Michael DOUBEZ
    Sep 12, 2008
Loading...

Share This Page