[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