Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ruby multi-module project, problem with types #903

Open
BernhardDenner opened this issue Feb 15, 2017 · 0 comments
Open

Ruby multi-module project, problem with types #903

BernhardDenner opened this issue Feb 15, 2017 · 0 comments
Labels

Comments

@BernhardDenner
Copy link

I have some troubles with a multi-module project using Ruby.

I'm creating Ruby wrappers for two different libraries, where one uses some types of the other lib.

Here a simplified form of the problem:
the header files
base.hpp

namespace base {
class Key {
 ...
};
}

tools.hpp

namespace base {
namespace tools {
class Modules {
...
  base::Key getKey();
};
}

with the following interface files
base.i

%module base
%{
#include "base.hpp"
%}
%include "base.hpp"

tools.i

%module tools
%{
#include "tools.hpp"
%}
%import base.i
%include "tools.hpp"

so far so good, but from the Ruby point of view I get

irb :1 > require 'tools'
irb :2 > k1 = Base::Key.new
 => #<Base::Key:0x... @__swigtype__="_p_base__Key">
irb :3 > m = Tools::Modules.new
 => #<Tools::Modules:0x... @__swigtype__="_p_tools__Modules">
irb :4 > k1 = m.get_key
 => #<SWIG::TYPE_p_base__Key:0x... @__swigtype__="_p_base__Key">
irb :5 > k2.is_a? Base::Key
 => false
irb :6 > k1.is_a? Base::Key
 => true

From my point of view, this is a wrong behaviour. I would expect to have k2.is_a? Base::Key evaluate to true.
But with this the return value of Moduels.get_key is useless, as it is an "empty" object, without the usual methods for Base::Key.

Did I do something wrong with my multi-module setup?
The example in the docu is about an extension with inheritance, which is not the case here.
Or is it simply a Bug?
What is this SWIG::TYPE_p_base__Key class? What is it used for? Is it just a "fallback" in case the correct class was not correctly setup?

After some debugging of the generated wrapper code, I came up with the following workaround:
tools.i

... same as above ...
%import "bsae.i"
%init {
  VALUE my_mBase = rb_define_module("Base");
  VALUE my_key = rb_define_class_under(my_mBase, "Key", rb_cObject);
  rb_const_remove(_mSWIG, rb_intern("TYPE_p_base__Key"));
  rb_const_set(_mSWIG, rb_intern("TYPE_p_base__Key"), my_key_klass);
}
...

I think the main problem here is, that the swig_type_info fields of the 'tools' extension is not initialized with the types coming from 'base.i'. SWIG generates a swig_type_info for Base::Key but it is not initialized with its corresponding "clientdata". So the function SWIG_NewPointerObj() uses this "fake" SWIG::TYPE_p_base__Key class for object creation.
My workaround redefines the internal SWIG constant to map to the correct class, such that the SWIG_NewPointerObj() uses the correct class.

@ojwb ojwb added the Ruby label Feb 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants
@ojwb @BernhardDenner and others