[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