Hi Stefan,
first of all thanks for your quick response. You put me on the right track. Your explanation clarified some C++/ Boost.Python issues I wasn't aware of before. Your sketched solution is exactly what I need. Below is the complete running example. Thanks Rainer ############################################################################## # # const_char_ptr.cpp # ############################################################################## #include <boost/python.hpp> #include <iostream> // Container Class struct ConstCharPtr { char const *x; std::string operator()() const { std::string s(x); return s; }; }; const char* x= "A.B"; // Class 'A' class A { public: A(): m_ccp(NULL) { }; int getName(const char *& ccp) {m_ccpr = ccp; ccp = x; return 1; } std::string operator()() const { std::string s(m_ccp); return s; }; private: const char* m_ccp; }; // Container class factory ConstCharPtr make_ccp() { return ConstCharPtr(); }; // the A::getName, adjusted to work with a ConstCharPtr argument int get_name(A &a, ConstCharPtr &ccp) { return a.getName(ccp.x);} namespace bp = boost::python; // expose to Python void export_ccp() { bp::class_<ConstCharPtr, boost::noncopyable> ccp("ConstCharPtr"); ccp.def("__init__", &make_ccp); // Make ConstCharPtr instances Python callable ccp.def("__call__", &ConstCharPtr::operator()); bp::class_<A>("A", "This is class A", bp::init< >()) .def("getName", &get_name) ; }; ############################################################################## # # Boost.Python wrapper: samplemodule.cpp # ############################################################################## #include <boost/python.hpp> #include <iostream> using namespace boost::python; // export function void export_ccp(); // const_char_ptr.cpp BOOST_PYTHON_MODULE(sample) { export_ccp(); }; ############################################################################## # # Python usage # ############################################################################## >>> from sample import * >>> a=A() >>> x=ConstCharPtr() >>> n=a.getName(x) >>> n 1 >>> x() 'A.B' // Bingo! Von: Stefan Seefeld <ste...@seefeld.name> An: cplusplus-sig@python.org Datum: 12.05.2011 15:39 Betreff: Re: [C++-sig] from_python conversion for a const char*& argument Gesendet von: cplusplus-sig-bounces+rainer.kluger=lbbw...@python.org 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... _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig ---------------------------------------------------------------------------------- LBBW-Info IT-Security: Die Nachricht war weder verschluesselt noch digital unterschrieben. Landesbank Baden-Wuerttemberg Anstalt des oeffentlichen Rechts Hauptsitze: Stuttgart, Karlsruhe, Mannheim, Mainz HRA 12704 Amtsgericht Stuttgart _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig