#1194 Wrong Ruby class for C++ subclass with same name as base

ruby (61)

When wrapping a C++ class hierarchy using two Ruby modules, and the subclass has the same name as the base class but is in a different namespace, the Ruby class information is wrong at runtime. The situation (shortened):

module base.i:
class Foo::Bar;

module sub.i:
class Foo::Sub::Bar;
Foo::Bar *bar();
Foo::Sub::Bar *subbar();

Now, when calling bar() from Ruby, the Ruby class of the returned object is Foo::Sub::Bar, where instead it should be Foo::Bar. The class of subbar() is Foo::Sub::Bar (which is correct):

bar: Foo::Sub::Bar
subbar: Foo::Sub::Bar

What's interesting is that the __swigtype__ is correct:

bar: _p_Foo__Bar
subbar: _p_Foo__Sub__Bar

When debugging with gdb, I can see that the entries in swig_types point to the same clientdata struct. So, I assume that somewhere the clientdata is set wrongly.

What's also interesting is that, with -DSWIGRUNTIME_DEBUG, the following cast list is printed for bar (I would expect _p_Foo__Bar to be the first cast in the list here):

SWIG_InitializeModule: type 0 _p_Foo__Bar
SWIG_InitializeModule: cast type _p_Foo__Sub__Bar
SWIG_InitializeModule: cast type _p_Foo__Bar

When changing the class name of Foo::Sub::Bar to Baz, the problem goes away.

Please extract the attached example, build and run it to reproduce the problem.

The version of SWIG is svn trunk 12817.


  • Robin Stocker

    Robin Stocker - 2011-10-08

    I found the source of the problem!

    In the generated code, in base_wrap.cxx, there's this variable declaration:
    swig_class SwigClassBar;

    In sub_wrap.cxx, there's the same declaration:
    swig_class SwigClassBar;

    So this is actually the same variable at runtime, and when assigning "SwigClassBar.klass" during module loading, the later assignment wins, thus leading to Foo::Sub::Bar.

    Renaming the second variable to SwigClassSubBar, or making the variables static solves the problem. I'll try to prepare a patch.

  • Robin Stocker

    Robin Stocker - 2011-10-08

    By the way, is there a reason the variable needs to be global at all? I see that it was changed in r6944:

    - Printv(klass->header, "\nswig_class c", valid_name, ";\n", NIL);
    + Printv(f_wrappers, "swig_class c", valid_name, ";\n\n", NIL);

  • William Fulton

    William Fulton - 2011-11-13
    • assigned_to: gga73 --> wsfulton
    • status: open --> closed-fixed
  • William Fulton

    William Fulton - 2011-11-13

    Fixed for swig-2.0.5, thanks for the patch in #3421876.


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks