Discussion:
[Swig-user] Problem using custom smart pointers as class member variables.
Giovanni De Toni
2017-06-10 10:54:25 UTC
Permalink
Hello swig-users,

I've run into a strange issue regarding using custom smart pointers with
SWIG.
I'm currently working on a C++ project (http://www.shogun-toolbox.org/) in
which
we started to use our custom smart pointer, which is called Some (its
implementation is rather
simple, please have a look here [1]), inside our codebase to substitute old
macros
which are used for memory management purposes.
We are using SWIG to offer interfaces to other programming languages.

SWIG generation of these interfaces has no problem, but I have some trouble
with the Python one
when I try to access to a class method through a member variable which is
wrapped
with our custom Some pointer. To be clearer, let's say we have two C++
classes:

class OtherClass {
public:
int one() { return 1; }
};

class MockClass {
public:
Some<OtherClass> tmp {new OtherClass()};
};

If I create a MockClass instance, and I try to access to the one() method
of OtherClass
there will be no problem (Some implements the -> operator):

MockClass test;
test.tmp->one(); //Works

However, when I try to do the same by using the Python interface, let's say:

a = MockClass();
a.tmp.one();

The Python interpreter complains and it shows this error:

AttributeError: 'SwigPyObject' object has no attribute 'one'.

It seems that SWIG does not understand that tmp is simply a wrapped
instance of OtherClass
and Some<> is just a "container" in which we store the pointer to the
object, hence it does not expose
the OtherClass methods.

I've been looking into SWIG docs (and old mailing list discussion) to
search for a solution
but I didn't find anything which could solve this problem.

Why does it behave like that? Perhaps am I missing some SWIG configuration
parameter inside .i files?

Best regards,
Giovanni De Toni

[1]
https://github.com/shogun-toolbox/shogun/blob/develop/src/shogun/base/some.h
William S Fulton
2017-07-01 15:21:22 UTC
Permalink
Post by Giovanni De Toni
Hello swig-users,
I've run into a strange issue regarding using custom smart pointers with
SWIG.
I'm currently working on a C++ project (http://www.shogun-toolbox.org/)
in which
we started to use our custom smart pointer, which is called Some (its
implementation is rather
simple, please have a look here [1]), inside our codebase to substitute
old macros
which are used for memory management purposes.
We are using SWIG to offer interfaces to other programming languages.
SWIG generation of these interfaces has no problem, but I have some
trouble with the Python one
when I try to access to a class method through a member variable which is
wrapped
with our custom Some pointer. To be clearer, let's say we have two C++
class OtherClass {
int one() { return 1; }
};
class MockClass {
Some<OtherClass> tmp {new OtherClass()};
};
If I create a MockClass instance, and I try to access to the one() method
of OtherClass
MockClass test;
test.tmp->one(); //Works
a = MockClass();
a.tmp.one();
AttributeError: 'SwigPyObject' object has no attribute 'one'.
It seems that SWIG does not understand that tmp is simply a wrapped
instance of OtherClass
and Some<> is just a "container" in which we store the pointer to the
object, hence it does not expose
the OtherClass methods.
I've been looking into SWIG docs (and old mailing list discussion) to
search for a solution
but I didn't find anything which could solve this problem.
Why does it behave like that? Perhaps am I missing some SWIG configuration
parameter inside .i files?
Has SWIG parsed your definition of Some and have you used %template? See
http://swig.org/Doc3.0/SWIGPlus.html#SWIGPlus_smart_pointers. This might be
the easiest way to support smart pointers, but the implementation of
shared_ptr might be one to copy. I think it is superior but requires a lot
more work.

William

Continue reading on narkive:
Loading...