[C++-sig] Re: C arrays solution
Raoul Gough
RaoulGough at yahoo.co.uk
Tue Oct 14 02:00:53 CEST 2003
"Niall Douglas" <s_sourceforge at nedprod.com> writes:
> On 13 Oct 2003 at 10:01, Raoul Gough wrote:
>
>> > Thoughts on the below? Is it worth you integrating similar
>> > functionality and thus all other bpl users can use it? Or is this
>> > too esoteric and/or demanding to warrant inclusion?
>> [snip]
>>
>> I can't really comment on this, because I don't understand what the
>> code is supposed to do. Can you explain the motivation for it?
>
> The motivation is with a single call to wrap C arrays. Let me give
> you an example:
>
> I have a class FXObjectList which is a bespoke container for
> FXObject's. Among the many fun things it does which normal containers
> would not it also returns the container's contents as a C array and
> provides another method returning the length. Let's call them
> FXObject *getData() and int getDataLen().
>
> Now when wrapping FXObjectList I already have FXObject wrapped - it
> does it's own thing and there's no problem. Just FXObjectList. Before
> I could not wrap FXObjectList without lots of custom code whereas
> with code like I previously posted, it becomes as simple as:
>
> boost::python::class_<FXObjectList,
> boost::noncopyable>("FXObjectList")
> .def("getData", MakeCArray(&FXObjectList::getData,
> &FXObjectList::getDataLen))
>
> And bam!, in one fell swoop the problem is solved.
>
> Another problem I have is that the library I am wrapping provides
> static const indexed lists of constant strings (providing stuff like
> DND target names and MIME types). It's very hard to provide these to
> python code but again with the above, bam! and the problem is solved.
>
> Lastly I have some code which unfortunately returns a pointer to a
> single value just so it can indicate "value is invalid" by returning
> a null pointer. In this situation a MakeCArray(&function, 1) means
> once again bam!, and the problem is solved.
>
>> I have the feeling that you may be reinventing one or two wheels as
>> well - e.g. have you considered using std::vector or boost::array, and
>> what about type_traits?
>
> I'm wrapping a large preexisting library which is not my own. It uses
> many idioms which make translation into python hard which has up
> until now made python wrappings for the library very tough to
> maintain.
Now I'm beginning to understand :-) You can't re-use (for instance)
boost::array because this library already does things its own way.
>
>> Also, I wonder about the use of member
>> function pointers - is there an easier way to get what you want?
>
> Not at all. Those member functions are the official interface for
> accessing the array's contents. They must be called at run-time to
> yield correct access.
It was more a question of how you inform your wrapper layer what
functions should be called. e.g. you could use a traits class, which
would take care of this on a per-type basis (assuming that the
functions to call don't vary from one object to another). Or you could
just use function overloading, something like the indexing::begin()
and indexing::end() functions for arrays.
>
>> > static void *carray;
>> > ...
>> > carray=(void *) new CArray<getArrayFn, getLenFn>(a, b);
>>
>> This look pretty suspect to me - what's going on here?
>
> More temporary code bootstrapping in static data. The actual
> implementation will use a generic functor class I'm writing to store
> the function pointers in a global list which is hash-indexed.
>
> As I previously mentioned, it was a proof of concept.
>
> Now I've explained, your thoughts on whether it would be of use to
> others?
Well, it's starting to make more sense to me. In fact, I think there
is already something similar to this which returns a Python iterator
instead of an indexing::iterator_pair. IIRC it's called
boost::python::range or similar. The iterator_pair (with the container
suite) has far more functionality than a Python iterator, of course.
To summarise: this boils down to a method for generating an
iterator_pair from an arbitrary object which has some way of
generating two iterators. Does that sound about right?
--
Raoul Gough.
(setq dabbrev-case-fold-search nil)
More information about the Cplusplus-sig
mailing list