[C++-sig] from_python conversion for a const char*& argument
Stefan Seefeld
stefan at seefeld.name
Thu May 12 15:28:15 CEST 2011
Hi Rainer,
On 2011-05-12 08:57, Rainer Kluger wrote:
>
> Hi
>
> I try to expose the following class to python (using gcc 4.5.1, boost
> 1_44_0, Python 2.7.1):
>
>
> // C++
> class A
> {
> public:
> int getName(const char*& name); // suppose the implementation
> assigns the const char* x = "foo"; variable to the ref-pointer
> }
>
> I'd like to expose this API as is and not alter the method interface so I
> think I'll have to do s.th. like this:
>
> ====================================
>
> # intended usage in Python:
>
>>>> import test
>>>> a = A()
>>>> x = const_char_ptr_ref()
>>>> y = a.getName(x)
>>>> x()
> 'foo'
>
> ====================================
>
>
> I followed the "recipes" of the python test example, realizing that
> - m1.cpp
> -extract.cpp
> and tried to get the things together, knowing that those example do not
> really match my use case.
>
> My understanding for what I need to do, are the following steps:
>
> (1) encapsulate the const char*& variable in a container class, let's
> say ConstCharPtrRef""
> (2) expose the ConstCharPtrRef class to Python
> (3) provide a factory function for the class exposed in the step (2)
> (4) expose the factory function from step (3)
Right.
> (5) provide an extractor function which extracts the "const char*&"
> variable from within the given python argument
> (6) register a from_python converter for the given type and the
> provided extractor function
I'm not sure I understand the need for (5) and (6). If you have defined
a ConstCharPtrRef C++ type, and exported it to Python, you will already
have converters between the two, so from within C++ you then can simply
access the ConstCharPtrRef members by whatever API you define in C++.
There is no need for extra converters at that point.
I'm also not sure the reference needs to be captured at that level, as
that's more of a call policy (for the A::getName member function) than
an aspect of the type.
Here is how I would approach it (caution: fully untested code):
struct ConstCharPtr
{
char const *x;
};
// A factory...
ConstCharPtr make_ccp(...);
// the A::getName, adjusted to work with a ConstCharPtr argument
int get_name(A const &a, ConstCharPtr const &ccp) { return a.getName(ccp);}
BOOST_PYTHON_MODULE(test)
{
// Export the ConstCharPtr type...
class_<ConstCharPtr, boost::noncopyable> ccp("ConstCharPtr", no_init);
// ...and define how to construct it
ccp.def("__init__", make_cpp);
// Export the A type...
class_<A> a("A");
// and export the getName member function
a.def("getName", get_name);
//...
}
I believe this should actually do what you want.
Stefan
--
...ich hab' noch einen Koffer in Berlin...
More information about the Cplusplus-sig
mailing list