Re: [pygccxml-development] Function adaptors
Brought to you by:
mbaas,
roman_yakovenko
From: Roman Y. <rom...@gm...> - 2009-08-18 17:45:43
|
2009/8/18 Berserker <ber...@ho...>: > You really made my life easier with this patch, thanks! Okey, in this case we are moving in the right direction :-) > Unfortunately I still have a (little) problem with virtual protected methods > :) May I ask to you post C++ code and the generated code with comments where you want to insert your code? > Everything works fine here :D, Good. > the problem is related to protected_virtual > method where Py++ > only generates Foo_wrapper::protected_virtual code (why?). I don't remember. I think there were serious problems in that area. After all, it is impossible to access protected functions out side of the class and this is the main problem. > Now consider this > Python code: > >> class PyFoo(Foo): >> def test_public_virtual(self): >> self.public_virtual() >> >> def public_virtual(self): >> Foo.public_virtual(self) >> >> def test_protected_virtual(self): >> self.protected_virtual() >> >> def protected_virtual(self): >> Foo.protected_virtual(self) >> >> foo = PyFoo() >> foo.test_virtual_public() >> foo.test_virtual_protected() > > foo.test_public_virtual() calls PyFoo.public_virtual() which calls > Foo_wrapper::default_public_virtual() > which calls Foo::public_virtual() (as expected) > > foo.test_protected_virtual() calls PyFoo.protected_virtual() which calls > Foo_wrapper::protected_virtual() > insted of a "Foo_wrapper::default_protected_virtual()", let's see the code > of "Foo_wrapper::protected_virtual()" > (without "customizations") > >> virtual void protected_virtual( ){ >> if( ::boost::python::override func_protected_virtual = >> this->get_override( "protected_virtual" ) ) >> func_protected_virtual( ); >> else{ >> this->::Foo::protected_virtual( ); >> } >> } > > Do you see the problem here? "func_protected_virtual" will always lead in a > "true" condition because of > our PyFoo.protected_virtual, so func_protected_virtual() invokes the Python > code which in turn invokes > the C++ wrapper code infinitely. I think that it will be easy to fix this > problem (we just need to create a > Foo_wrapper::default_protected_virtual as for the virtual public Yes and I considered this problem in the past. Py++ support non public virtual functions is limited to "template method" design pattern. I mean it allows to replace\implement them in Python, but not to access their implementation in C++. You are welcome to try to play with those problem and come up with solution. If you can modify source code - I suggest you to do this. Another possible solution is to create adaptors in C++ code and expose them, instead of the library classes. >> May I ask you to create an article or document, with examples, which >> explains how to use Py++ for embedding? > > Sure, I'd like to help you in writing an "embedding tutorial" but I need to > fix the last issues in > my TODO, for example I noticed that in this release you make use of > "boost::python::pure_virtual" which is > correct but causes me lots of headaches :) , here is a short explanation of > the problem: > ""boost::python::pure_virtual" is a custom "visitor" that adds a default > implementation (function "pure_virtual_called") > which raises an exception. Here it is the code: > >> void BOOST_PYTHON_DECL pure_virtual_called() >> { >> PyErr_SetString(PyExc_RuntimeError, "Pure virtual function called"); >> throw_error_already_set(); >> } > > In the case of a C++ to Python calls, I would need, as usual, to restore the > right PyThreadState > before calling any CPython API (PyErr_SetString in the above's code), but I > have no options here to customize > "pure_virtual_called". Probably I'll ovverride in Py++ the identifier > "::boost::python::pure_virtual" with a > custom one, but I still need to think/work on this (I love the "override" > feature in Py++ :) ). This one is fixed. I will commit the code soon. > The last problem I want to report is in the files name generation: they > follow the classes names (in the "Foo" > example Py++ creates a "Foo.pypp.cpp" file) but in the registration code > (where BOOST_PYTHON_MODULE > is defined), the include code is always in lower case (#include > "foo.pypp.cpp" in our example) and this > causes problems when I compile the code under linux. > Actually I'm using this workaround: > >> original_write_file = >> pyplusplus.file_writers.multiple_files.multiple_files_t.write_file >> def make_lower_write_file(self, fpath, content): >> splittedPath = os.path.split(fpath) >> fpath = os.path.join(splittedPath[0], splittedPath[1].lower()) >> original_write_file(self, fpath, content) >> pyplusplus.file_writers.multiple_files.multiple_files_t.write_file = >> make_lower_write_file I think, I fixed this problem. Try to generate code on Linux, don't take it as is from Windows. File names is not the only problem. HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |