[C++-sig] In a C++ extension, how to use a C++ class exported in another extension

David Abrahams dave at boost-consulting.com
Mon Jul 4 22:59:37 CEST 2005


"Ralf W. Grosse-Kunstleve" <rwgk at yahoo.com> writes:

> --- David Abrahams <dave at boost-consulting.com> wrote:
>> > This solution is based on what I found in SWIG-1.3.24/Lib/python/pyrun.swg.
>> > At the heart of the solution is this simple fragment:
>> >
>> >     static void* extract(PyObject* op) \
>> >     { \
>> >         if (std::strcmp(op->ob_type->tp_name, "PySwigObject") != 0)
>> >     return 0; \
>> 
>> Isn't there a type object somewhere you can compare ob_type with?
>
> It seemed hard to me. Here is what I understand:
>
> SWIG is a wrapper generator (more similar to Pyste than to Boost.Python). In
> the SWIG-1.3.24/Examples/python/class that I was using, SWIG copies a big chunk
> of code into the generated example_wrap.cxx. This includes the complete
> definition of the type object for PySwigObject. The type definition is
> implemented as a group of static objects in this function: 
>
> SWIGRUNTIME PyTypeObject*
> PySwigObject_GetType();
>
> We'd have to get hold of this function, which I believe will complicate the
> linking severely. But even if we did, it wouldn't get us very far since each
> SWIG-generated extension has its own version of the type object, with its own
> address. That's probably why I found this function:
>
> SWIGRUNTIMEINLINE int
> PySwigObject_Check(PyObject *op) {
>   return ((op)->ob_type == PySwigObject_GetType())
>     || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0);
> }
>
> I am still wondering why SWIG does "one or the other" and not simply the more
> general "other". The best explanation I can find for myself is optimization for
> speed (pointer equivalence vs. string comparison). Anyway, for me the
> conclusion was clear: it is definitely not worth complicating the build process
> for such a minute gain. If the Python/C++ combination is used sensibly the
> runtime difference will be unmeasurable anyway.

You have grown very wise, O grasshopper.

>> Heh, so that's how they do it.  Pretty lame, IMO.
>
> Hey, let's be politically correct: Pretty basic, at that level.
> They decided to put all their energy into a special parser, which
> clearly has some advantages if you have to deal a lot with C-style
> interfaces. E.g. the int* question is coming up a lot.

You shall now be my master.

>> Well, inheritance
>> won't work; a swig-wrapped Derived won't be able to be passed where a
>> Base is expected.  If that doesn't matter, it's fine.
>
> Is there a way to write something like:
>
>     bases_of<Circle, mpl::vector<Shape> >();

In principle, yes, but it would take some nontrivial coding.

>> >     boost_python_swig_args_ext.show(c.this)
>> >     boost_python_swig_args_ext.show(s.this)
>> 
>> You should have part of the test that shows non-matching types are
>> rejected.
>
> I figured rejection is tested since the overload resolution couldn't work
> otherwise. 

Oh, are you testing overload resolution?  If so, that's enough.

> What exactly do you have in mind?
>
>> > David, would you want to include the core of swig_args_ext.cpp in,
>> > e.g., boost/python/swig_arg.h? I think it would be a valuable
>> > addition. There are many SWIG-wrapped libraries. People could easily
>> > use them while writing their own extensions with Boost.Python.
>> 
>> Sounds great!  Needs docs, of course ;-)
>
> Would you be happy with a page like I wrote for the pickle suite,
> linked from the main page, e.g. "SWIG interoperability"?

Great!

> But I still have a question. I don't really like the interface I came up with
> since it requires two steps:
>
> 1. BOOST_PYTHON_SWIG_ARG(Circle)
>
> 2. swig_arg<Circle>();
>
> It would be nicer if one could simply write
>
>   swig_arg<Circle>("Circle");
>
> Is there any way this could be achieved?

Well of course! No need to build a specialization of swig_arg; the
only thing you're doing with that specialzation is prepending "t" to
the name.  You can just build the string inside the swig_arg ctor.

Are you sure you want to write "Circle" twice?  Seems to me that

      BOOST_PYTHON_SWIG_ARG(Circle)

might be better.

> Actually, here is another question: would it be best to wait until Boost 1.33
> is out?

We are in a main trunk feature-freeze, but doing it now on a branch
would be better than waiting.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com




More information about the Cplusplus-sig mailing list