From dubois1 at llnl.gov Sun Feb 6 07:17:45 2000 From: dubois1 at llnl.gov (Paul F. Dubois) Date: Sat, 5 Feb 2000 22:17:45 -0800 Subject: [C++-SIG] design question - python extensions in C++ In-Reply-To: <000101a90625$b6ffc1c0$bbe1aec7@bathsheba.mindspring.com> Message-ID: David Abrahams and Barry Scott have also done quite a lot of improvement in this area. I don't have time right now to get into this but you should compare notes with them. There is some concern about recent changes to the C++ standard that they can brief you on. As I said in my talk at IPC8 I am looking to pass CXX off to some new caretakers since my current work does not involve C++. In the new approach, you inherit from PyObject to make a new object type. I liked what I did on the CXX_Objects side but was not satisfied with the extension side, so I'm glad that others have taken up the call. > -----Original Message----- > From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org]On > Behalf Of Brad Venner > Sent: Friday, February 08, 1980 12:14 PM > To: c++-sig at python.org > Subject: [C++-SIG] design question - python extensions in C++ > > > Greetings, > > I would like to get some feedback regarding some design decisions on > some work I have done on C++ extensions. > > The design philosopy in CXX_Extensions by P. Dubois is to create a > unique type object for each C++ class. This is basically the approach > used in CPython, where each python type has an associated type object. > These type objects are created through the use of a templated class in > which the class being defined is given as an argument to the template > class. In my use of CXX, I found myself writing very similar code for > each class I derived. For example, each class needed a getattr > function that was identical to all the other getattr functions in > every class. This can partially be addressed by creating an > intermediate class that provides a default implementation of some of > these common functions. > > In several posts in December, 1999, John Skaller proposed and outlined > in detail an approach in which there is a single python type object > that parallels a single C++ abstract base class. Since fools rush in > where angels fear to tread, I have implemented some of the ideas > outlined in J. Skaller's posts. The basic idea of the code is as > follows: > > class CppPyObject: public PyObject { > public: > virtual int print() {throw TypeError("unimplemented_method");} > } > class CppPyType { > // code to initialize static _typeobject struct > PyTypeObject * type_object(); > public: > static bool check(PyObject * pyob) > { return pyob && pyob->ob_type==type_object(); } > static int print(PyObject* pyob) { > try { > if(check(pyob)) { > static_cast(pyob)->print(); > return 0; > } > // error handling & return > } > } > CppPyType& cpp_type() { > // singleton pattern > static ObjectType type; > return type; > } > class MyObject: public CppPyObject { > private: > MyObject() { > ob_refcnt = 1; > ob_type=cpp_type().type_object(); > } > public: > PyObject* create(PyObject*, PyObject*); > virtual int print() {cout << "It's alive";} > } > > This approach seems to work, and reduces the amount of work required to > implement the virtual functions, since Python-specific stuff can be > moved into the default function, including error checking. As > discussed by Skaller, methods can be added by overloading the virtual > getattr function in the concrete class. Taking Skaller's hint, I used > stl::map<> to implement the method tables. > > There are several design decisions now that I would like to get > feedback on. One problem I'm running into now is how to safely > convert PyObject*'s to the appropriate and specific C++ > implementation. In the CXX approach, there would be a static function > MyObject::check. Again, this is similar to the CPython approach, > which checks to see if the address of the type object since one-to-one > correspondence with the type object. In the Skaller approach, the > type-checking routine has to be (can be?) implemented within the C++ > iterface class CppPyObject. The design I am attempting is to use > class-specific identifiers (static strings) in creation-type classes > and the use a virtual "check" function to perform type checking using > string comparison. For example, > > PyObject* function(PyObject *self, PyObject* args) { > Tuple a(args); > // check length > PyObject* arg1 = a[0].ptr(); > ObjectProtocol * arg1 = static_cast(arg1); > if(arg1->check("MyObject")) > MyObject * myob = static_cast(arg1); > // do useful stuff > } > else throw TypeError("Function requires MyObject argument"); > } > > Does anyone have a better idea or approach that I should consider. > > A second problem is how to check for to see if a PyObject* implements > a particular Python/C++ interface. It would be nice to write C++ > functions that did not require conversion to a specific creation-type > but instead could check to see if a creation-type implemented a > particular interface, and then cast the PyObject* to a pointer to the > interface. Python checks for it's interface "types" (number, > sequence, mapping) by checking for a null-pointer in the type object. > A C++ equivalent is needed but I don't really see how to do it. > > Anyway, I appreciate any feedback on these or other issues. My e-mail > address at work is venner.brad at epa.gov, at home is > vennerbc at mindspring.com. > > > > > > _______________________________________________ > C++-SIG maillist - C++-SIG at python.org > http://www.python.org/mailman/listinfo/c++-sig > From skaller at maxtal.com.au Sun Feb 6 15:10:18 2000 From: skaller at maxtal.com.au (skaller) Date: Mon, 07 Feb 2000 01:10:18 +1100 Subject: [C++-SIG] design question - python extensions in C++ References: <000101a90625$b6ffc1c0$bbe1aec7@bathsheba.mindspring.com> Message-ID: <389D80CA.D5862E64@maxtal.com.au> Brad Venner wrote: > > There are several design decisions now that I would like to get > feedback on. One problem I'm running into now is how to safely > convert PyObject*'s to the appropriate and specific C++ > implementation. Unfortunately, this is a necessary evil of object oriented programming -- covariant typing requires a dynamic cast. > PyObject* function(PyObject *self, PyObject* args) { > Tuple a(args); > // check length > PyObject* arg1 = a[0].ptr(); > ObjectProtocol * arg1 = static_cast(arg1); > if(arg1->check("MyObject")) { > MyObject * myob = static_cast(arg1); > // do useful stuff > } > else throw TypeError("Function requires MyObject argument"); > } > > Does anyone have a better idea or approach that I should consider. Why not just use a dyanamic cast? MyObject *o = dynamic_cast(arg1); This should work because the MyObject is derived from PyObject. > A second problem is how to check for to see if a PyObject* implements > a particular Python/C++ interface. It would be nice to write C++ > functions that did not require conversion to a specific creation-type > but instead could check to see if a creation-type implemented a > particular interface, and then cast the PyObject* to a pointer to the > interface. Python checks for it's interface "types" (number, > sequence, mapping) by checking for a null-pointer in the type object. > A C++ equivalent is needed but I don't really see how to do it. This is tricky. One way is to further factor the abstraction PyObject by making abstract bases PySequence and PyMapping. Then (in theory) you can again use a dynamic cast: if (dynamic_cast(object)) { .. a sequence .. } else { .. not a sequence .. } -- John (Max) Skaller, mailto:skaller at maxtal.com.au 10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850 homepage: http://www.maxtal.com.au/~skaller download: ftp://ftp.cs.usyd.edu/au/jskaller From VENNER.BRAD at epamail.epa.gov Tue Feb 8 14:52:20 2000 From: VENNER.BRAD at epamail.epa.gov (BRAD VENNER) Date: Tue, 08 Feb 2000 08:52:20 -0500 Subject: [C++-SIG] design question - python extensions in C++ Message-ID: An embedded and charset-unspecified text was scrubbed... Name: not available URL: From VENNER.BRAD at epamail.epa.gov Tue Feb 8 15:18:50 2000 From: VENNER.BRAD at epamail.epa.gov (BRAD VENNER) Date: Tue, 08 Feb 2000 09:18:50 -0500 Subject: [C++-SIG] design question - python extensions in C++ Message-ID: An embedded and charset-unspecified text was scrubbed... Name: not available URL: From justinlundeen at hotmail.com Sat Feb 12 04:33:20 2000 From: justinlundeen at hotmail.com (Justin L.) Date: Fri, 11 Feb 2000 21:33:20 CST Subject: [C++-SIG] Hello... Message-ID: <20000212033320.10813.qmail@hotmail.com> Hello all, I say all because I don't know if this is going to one or more than one person :) Anyway, I joined this SIG looking for some help in programming games. I'd like to start small, then work my way up to like wrestling and sports games, then make a long adventure game like Final Fantasy games using the Python C++ program. So if you could help me out in ANY way at all I'd REALLY appreciate it, my email is, justinlundeen at hotmail.com ICQ UIN-46615389 AOL-JLUNEEN662 Thanks alot!! Justin R. Lundeen ______________________________________________________ Get Your Private, Free Email at http://www.hotmail.com