[pygccxml-commit] SF.net SVN: pygccxml: [65] pyplusplus_dev/docs
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2006-05-08 17:08:39
|
Revision: 65 Author: roman_yakovenko Date: 2006-05-08 00:00:13 -0700 (Mon, 08 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=65&view=rev Log Message: ----------- adding introduction to call wrapper policies Added Paths: ----------- pyplusplus_dev/docs/call_wrapper_policies/ pyplusplus_dev/docs/call_wrapper_policies/introduction.rest pyplusplus_dev/docs/call_wrapper_policies/www_configuration.py Added: pyplusplus_dev/docs/call_wrapper_policies/introduction.rest =================================================================== --- pyplusplus_dev/docs/call_wrapper_policies/introduction.rest (rev 0) +++ pyplusplus_dev/docs/call_wrapper_policies/introduction.rest 2006-05-08 07:00:13 UTC (rev 65) @@ -0,0 +1,241 @@ +===================== +call wrapper policies +===================== + +.. contents:: Table of contents + +------------------- +What is useful for? +------------------- +Not all C++ functions could be exposed to Python as is. For example, next function +could not be exposed: +:: + + void get_size( int& size ); + +In order to expose ``get_size`` function, an user need to create next wrapper: +:: + + int get_size_wrapper( ){ + int size(0); + get_size( size ); + return size; + } + +|cwp| will provide the user with simple and intuitive way to instruct +`pyplusplus`_ to generate right wrapper. Also, it will be possible to create +a custom policies. + +-------- +Analysis +-------- + +C++ function arguments usage +---------------------------- + +In C++ function argument can be used to: + +* to pass some data to function ( in ) + + there is no need to return variable from the function + +* to return some data from function ( out ) + + there is no need to force Python programmer to pass the variable as argument + to the function + +* both ( in/out ) + +Function-wrapper signature will be a little bit different in every case. + +Variable names +-------------- +I think it should be possible to apply few |cwp| on a single function. Thus, it +will be possible to create few convinience function, from one single function. +The main,read unresolved, issue, is management of variable names within function-wrapper. +I see next problems, that we should solve, before proceeding to implementation: + +1. To share variable name, between different pieces of code. + + Right now I think, that every |cwp| will have ``pre-call`` and ``post-call`` + code creators. This design will allow the user to mix few |cwp|'s within + single function-wrapper. + +2. To insure name uniqueness. + +3. To give meaningful name. + +I think, that is it very easy to solve the problem, if I remove "readability" +requirement. + +Call policies +------------- +I don't have any solution to the next problem. +I am going to change a little an example, from `boost.python`_ tutorials: +http://www.boost.org/libs/python/doc/tutorial/doc/html/python/functions.html#python.call_policies +:: + + //C++ code + struct Y + { + X x; Z* z; + int z_value() { return z->value(); } + }; + + X& f(Y& y, Z* z, int& error) + { + y.z = z; + return y.x; + } + + //boost.python code + def("f", f, return_internal_reference<1, with_custodian_and_ward<1, 2> >() ); + +What is the difference? Function ``f`` now takes 3rd argument - ``int&``. This +function could not be called from `Python`_. ( Hint: numbers are immutable +objects in `Python`_ ). So in order to expose function ``f`` to `Python`_, +an user need to create a wrapper. And now he has a problem: how to wrap the function? + +I see only one solution user have to change signature of function ``f``. +Now some speculations: + +1. May be it is possible with `boost.python`_ library to set call policies on the + part of the return value? + :: + + boost::tuple f_wrapper( Y& y, Z* z ){ + int error(0); + X& x = f( y, z, error ); + return boost::tuple<X&, int>( x, error ); + } + + def("f", f_wrapper, smart call policies that will work only on first element within the tuple ); + +2. May be it is possible to create boost.python ``object`` with life-time management + hint? + :: + + boost::python::tuple f_wrapper( Y& y, Z* z ){ + int error(0); + X& x = f( y, z, error ); + boost::python::object x_obj( x, x is internal reference of y ); + return boost::python::make_tuple( x_obj, error ); + } + +Anyway, I think we will just ignore the problem - software ( == boost.python ) +should not be perfect - it should work in most ( != all ) cases! + +------------ +Common |cwp| +------------ +Those names are not final and could( may be should ) be changed. + +immutable by reference +----------------------- +:: + + //function to be exported + something f( int& i, std::string& str ) + +I suppose this is very common use case. More over this use case `pyplusplus`_ +can and will treat by its own - no user action is needed. The wrapper +generated by `pyplusplus`_ will very similar to the next code: +:: + + void f_wrapper( const int& i, const std::string& str ){ + int i_out( i ); + std::string str_out( str ); + boost::python::object f_return = f( i_out, str_out ); + return boost::python::make_tuple( f_return, i, str ); + } + + +The only customization available for user is to setup argument type: +[in\|out\|in,out] + +array +----- +Arrays are a little bit different beasts. Python does not have arrays. +So, `pyplusplus`_, should implement arrays convertion: from/to C++/Python. +This is not the only difference, consider next function: +:: + + void fill( char* buffer, int index ){ + buffer[ index ] = 'c'; + } + + +There are few ways to expose this function: +:: + + ??? fill_wrapper( boost::python:list buffer, index ){ + long buffer_size = boost::python::extract<long>( buffer.attr("__len__") ); + boost::scoped_array<char> buffer_( new char[ buffer_size ] ); + for( long i = 0; i < buffer_size; ++i ){ + buffer_[ i ] = boost::python::extract<char>( buffer[i] ); + } + fill( buffer_.get(), index ); + //Now the question: how to return buffer_ to the caller? + //by constructing new list? + boost::python::list return_; + for( long i = 0; i < buffer_size; ++i ){ + return_.insert( i, buffer_[i] ); + } + return return_; + //or by modifying the buffer argument? In this case `pyplusplus`_ will + //delete all items from buffer and will copy into it items from buffer_ + //variable. + } + +Arrays size +~~~~~~~~~~~ +1. static array - size of array is known at compile time. +2. dynamic array + + + size of array is one of the function arguments + + + other ( will not be implemented in the first phase ) + + - size of array is some global/local variable + + - ize of array is returned by invocation some function + + +status as exception +------------------- +There a lot of code, that returns success status and/or error description by +using one of the function arguments. It will be possible to instruct `pyplusplus`_ +to create wrapper for those functions, that will throw exception. +:: + + bool do_smth( error_description& error_desc ); + + bool do_smth_wrapper(){ + error_description error_desc; + bool return_ = do_smth( error_desc ); + if( some user code that will check that error_desc contains error ){ + throw some user code that will construct an exception from the error_desc; + } + return return_; + } + +pythread safe +------------- +Why not :-)? See next FAQ: http://boost.org/libs/python/doc/v2/faq.html#threadsupport +So, how `pyplusplus`_ can help? `pyplusplus`_ can generate exception safe code, +that will acquire and release Python global interpreter lock. + + +.. _`pyplusplus` : ./../pyplusplus.html +.. |cwp| replace:: *"call wrapper policies"* +.. _`boost.python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: Added: pyplusplus_dev/docs/call_wrapper_policies/www_configuration.py =================================================================== --- pyplusplus_dev/docs/call_wrapper_policies/www_configuration.py (rev 0) +++ pyplusplus_dev/docs/call_wrapper_policies/www_configuration.py 2006-05-08 07:00:13 UTC (rev 65) @@ -0,0 +1,2 @@ +name = 'call wrapper policies' +main_html_file = 'introduction.html' \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |